@dxos/react-ui-editor 0.8.2-main.12df754 → 0.8.2-main.30e4dbb

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/dist/lib/browser/index.mjs +1178 -1110
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/browser/testing/index.mjs.map +2 -2
  5. package/dist/lib/node/index.cjs +1386 -1319
  6. package/dist/lib/node/index.cjs.map +4 -4
  7. package/dist/lib/node/meta.json +1 -1
  8. package/dist/lib/node/testing/index.cjs.map +2 -2
  9. package/dist/lib/node-esm/index.mjs +1178 -1110
  10. package/dist/lib/node-esm/index.mjs.map +4 -4
  11. package/dist/lib/node-esm/meta.json +1 -1
  12. package/dist/lib/node-esm/testing/index.mjs.map +2 -2
  13. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts +1 -1
  14. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -1
  15. package/dist/types/src/{stories/InputMode.stories.d.ts → components/EditorToolbar/EditorToolbar.stories.d.ts} +3 -7
  16. package/dist/types/src/components/EditorToolbar/EditorToolbar.stories.d.ts.map +1 -0
  17. package/dist/types/src/components/EditorToolbar/blocks.d.ts +4 -3
  18. package/dist/types/src/components/EditorToolbar/blocks.d.ts.map +1 -1
  19. package/dist/types/src/components/EditorToolbar/comment.d.ts +4 -3
  20. package/dist/types/src/components/EditorToolbar/comment.d.ts.map +1 -1
  21. package/dist/types/src/components/EditorToolbar/formatting.d.ts +4 -3
  22. package/dist/types/src/components/EditorToolbar/formatting.d.ts.map +1 -1
  23. package/dist/types/src/components/EditorToolbar/headings.d.ts +4 -3
  24. package/dist/types/src/components/EditorToolbar/headings.d.ts.map +1 -1
  25. package/dist/types/src/components/EditorToolbar/image.d.ts +16 -0
  26. package/dist/types/src/components/EditorToolbar/image.d.ts.map +1 -0
  27. package/dist/types/src/components/EditorToolbar/lists.d.ts +4 -3
  28. package/dist/types/src/components/EditorToolbar/lists.d.ts.map +1 -1
  29. package/dist/types/src/components/EditorToolbar/search.d.ts +17 -0
  30. package/dist/types/src/components/EditorToolbar/search.d.ts.map +1 -0
  31. package/dist/types/src/components/EditorToolbar/util.d.ts +11 -17
  32. package/dist/types/src/components/EditorToolbar/util.d.ts.map +1 -1
  33. package/dist/types/src/components/EditorToolbar/view-mode.d.ts +4 -3
  34. package/dist/types/src/components/EditorToolbar/view-mode.d.ts.map +1 -1
  35. package/dist/types/src/defaults.d.ts.map +1 -1
  36. package/dist/types/src/extensions/annotations.d.ts.map +1 -1
  37. package/dist/types/src/extensions/autocomplete.d.ts.map +1 -1
  38. package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
  39. package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
  40. package/dist/types/src/extensions/automerge/defs.d.ts.map +1 -1
  41. package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -1
  42. package/dist/types/src/extensions/automerge/update-codemirror.d.ts.map +1 -1
  43. package/dist/types/src/extensions/awareness/awareness.d.ts.map +1 -1
  44. package/dist/types/src/extensions/blast.d.ts.map +1 -1
  45. package/dist/types/src/extensions/command/command.d.ts.map +1 -1
  46. package/dist/types/src/extensions/command/hint.d.ts.map +1 -1
  47. package/dist/types/src/extensions/command/menu.d.ts.map +1 -1
  48. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  49. package/dist/types/src/extensions/debug.d.ts.map +1 -1
  50. package/dist/types/src/extensions/dnd.d.ts.map +1 -1
  51. package/dist/types/src/extensions/factories.d.ts.map +1 -1
  52. package/dist/types/src/extensions/folding.d.ts.map +1 -1
  53. package/dist/types/src/extensions/listener.d.ts.map +1 -1
  54. package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
  55. package/dist/types/src/extensions/markdown/changes.d.ts.map +1 -1
  56. package/dist/types/src/extensions/markdown/debug.d.ts.map +1 -1
  57. package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
  58. package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
  59. package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
  60. package/dist/types/src/extensions/markdown/image.d.ts.map +1 -1
  61. package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
  62. package/dist/types/src/extensions/markdown/table.d.ts.map +1 -1
  63. package/dist/types/src/extensions/mention.d.ts.map +1 -1
  64. package/dist/types/src/extensions/modes.d.ts +5 -5
  65. package/dist/types/src/extensions/modes.d.ts.map +1 -1
  66. package/dist/types/src/extensions/preview/preview.d.ts.map +1 -1
  67. package/dist/types/src/extensions/selection.d.ts.map +1 -1
  68. package/dist/types/src/extensions/typewriter.d.ts.map +1 -1
  69. package/dist/types/src/hooks/index.d.ts +0 -1
  70. package/dist/types/src/hooks/index.d.ts.map +1 -1
  71. package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
  72. package/dist/types/src/stories/story-utils.d.ts.map +1 -1
  73. package/dist/types/src/testing/RefPopover.d.ts.map +1 -1
  74. package/dist/types/src/util/cursor.d.ts.map +1 -1
  75. package/dist/types/src/util/debug.d.ts.map +1 -1
  76. package/dist/types/src/util/dom.d.ts.map +1 -1
  77. package/dist/types/src/util/facet.d.ts.map +1 -1
  78. package/dist/types/src/util/react.d.ts.map +1 -1
  79. package/dist/types/tsconfig.tsbuildinfo +1 -1
  80. package/package.json +30 -28
  81. package/src/components/EditorToolbar/EditorToolbar.stories.tsx +90 -0
  82. package/src/components/EditorToolbar/EditorToolbar.tsx +30 -31
  83. package/src/components/EditorToolbar/blocks.ts +27 -6
  84. package/src/components/EditorToolbar/comment.ts +11 -4
  85. package/src/components/EditorToolbar/formatting.ts +34 -7
  86. package/src/components/EditorToolbar/headings.ts +9 -8
  87. package/src/components/EditorToolbar/image.ts +16 -0
  88. package/src/components/EditorToolbar/lists.ts +26 -7
  89. package/src/components/EditorToolbar/search.ts +19 -0
  90. package/src/components/EditorToolbar/util.ts +14 -14
  91. package/src/components/EditorToolbar/view-mode.ts +9 -8
  92. package/src/extensions/modes.ts +5 -6
  93. package/src/extensions/preview/preview.ts +1 -1
  94. package/src/hooks/index.ts +0 -1
  95. package/src/testing/RefPopover.tsx +4 -4
  96. package/dist/types/src/hooks/useActionHandler.d.ts +0 -4
  97. package/dist/types/src/hooks/useActionHandler.d.ts.map +0 -1
  98. package/dist/types/src/stories/InputMode.stories.d.ts.map +0 -1
  99. package/src/hooks/useActionHandler.ts +0 -12
  100. package/src/stories/InputMode.stories.tsx +0 -124
@@ -40,7 +40,7 @@ import { tags as tags2 } from "@lezer/highlight";
40
40
  import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
41
41
 
42
42
  // packages/ui/react-ui-editor/src/components/EditorToolbar/EditorToolbar.tsx
43
- import React, { useCallback } from "react";
43
+ import React3, { memo, useCallback } from "react";
44
44
  import { ElevationProvider } from "@dxos/react-ui";
45
45
  import { MenuProvider, ToolbarMenu, createGapSeparator, useMenuActions } from "@dxos/react-ui-menu";
46
46
  import { textBlockWidth } from "@dxos/react-ui-theme";
@@ -52,692 +52,110 @@ import { createMenuAction, createMenuItemGroup } from "@dxos/react-ui-menu";
52
52
  var useEditorToolbarState = (initialState = {}) => {
53
53
  return useMemo(() => live(initialState), []);
54
54
  };
55
- var createEditorAction = (payload, icon, label = [
56
- `${payload.type} label`,
57
- {
58
- ns: translationKey
59
- }
60
- ], id = payload.type) => createMenuAction(id, {
61
- icon,
62
- label,
63
- ...payload
64
- });
55
+ var createEditorAction = (id, invoke, properties) => {
56
+ const { label = [
57
+ `${id} label`,
58
+ {
59
+ ns: translationKey
60
+ }
61
+ ], ...rest } = properties;
62
+ return createMenuAction(id, invoke, {
63
+ label,
64
+ ...rest
65
+ });
66
+ };
65
67
  var createEditorActionGroup = (id, props, icon) => createMenuItemGroup(id, {
66
68
  icon,
67
69
  iconOnly: true,
68
70
  ...props
69
71
  });
70
- var editorToolbarSearch = createEditorAction({
71
- type: "search"
72
- }, "ph--magnifying-glass--regular");
73
72
 
74
- // packages/ui/react-ui-editor/src/components/EditorToolbar/blocks.ts
75
- var createBlockGroupAction = (value) => createEditorActionGroup("block", {
76
- variant: "toggleGroup",
77
- selectCardinality: "single",
78
- value
79
- });
80
- var createBlockActions = (value, blankLine) => Object.entries({
81
- blockquote: "ph--quotes--regular",
82
- codeblock: "ph--code-block--regular",
83
- table: "ph--table--regular"
84
- }).map(([type, icon]) => {
85
- return createEditorAction({
86
- type,
87
- checked: type === value,
88
- ...type === "table" && {
89
- disabled: !!blankLine
90
- }
91
- }, icon);
92
- });
93
- var createBlocks = (state) => {
94
- const value = state?.blockQuote ? "blockquote" : state.blockType ?? "";
95
- const blockGroupAction = createBlockGroupAction(value);
96
- const blockActions = createBlockActions(value, state.blankLine);
97
- return {
98
- nodes: [
99
- blockGroupAction,
100
- ...blockActions
101
- ],
102
- edges: [
103
- {
104
- source: "root",
105
- target: "block"
106
- },
107
- ...blockActions.map(({ id }) => ({
108
- source: blockGroupAction.id,
109
- target: id
110
- }))
111
- ]
112
- };
113
- };
73
+ // packages/ui/react-ui-editor/src/extensions/annotations.ts
74
+ import { StateField } from "@codemirror/state";
75
+ import { Decoration, EditorView } from "@codemirror/view";
76
+ import { isNotFalsy } from "@dxos/util";
114
77
 
115
- // packages/ui/react-ui-editor/src/components/EditorToolbar/comment.ts
116
- var commentLabel = (comment, selection) => comment ? "selection overlaps existing comment label" : selection === false ? "select text to comment label" : "comment label";
117
- var createCommentAction = (label) => createEditorAction({
118
- type: "comment",
119
- testId: "editor.toolbar.comment"
120
- }, "ph--chat-text--regular", label);
121
- var createComment = (state) => ({
122
- nodes: [
123
- createCommentAction([
124
- commentLabel(state.comment, state.selection),
125
- {
126
- ns: translationKey
127
- }
128
- ])
129
- ],
130
- edges: [
131
- {
132
- source: "root",
133
- target: "comment"
134
- }
135
- ]
78
+ // packages/ui/react-ui-editor/src/util/facet.ts
79
+ import { Facet } from "@codemirror/state";
80
+ var singleValueFacet = (defaultValue) => Facet.define({
81
+ // Called immediately.
82
+ combine: (providers) => {
83
+ return providers[0] ?? defaultValue;
84
+ }
136
85
  });
137
86
 
138
- // packages/ui/react-ui-editor/src/components/EditorToolbar/formatting.ts
139
- var formats = {
140
- strong: "ph--text-b--regular",
141
- emphasis: "ph--text-italic--regular",
142
- strikethrough: "ph--text-strikethrough--regular",
143
- code: "ph--code--regular",
144
- link: "ph--link--regular"
87
+ // packages/ui/react-ui-editor/src/util/cursor.ts
88
+ var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
89
+ var defaultCursorConverter = {
90
+ toCursor: (position) => position.toString(),
91
+ fromCursor: (cursor) => parseInt(cursor)
145
92
  };
146
- var createFormattingGroup = (formatting) => createEditorActionGroup("formatting", {
147
- variant: "toggleGroup",
148
- selectCardinality: "multiple",
149
- value: Object.keys(formats).filter((key) => !!formatting[key])
150
- });
151
- var createFormattingActions = (formatting) => Object.entries(formats).map(([type, icon]) => createEditorAction({
152
- type,
153
- checked: !!formatting[type]
154
- }, icon));
155
- var createFormatting = (state) => {
156
- const formattingGroupAction = createFormattingGroup(state);
157
- const formattingActions = createFormattingActions(state);
158
- return {
159
- nodes: [
160
- formattingGroupAction,
161
- ...formattingActions
162
- ],
163
- edges: [
164
- {
165
- source: "root",
166
- target: "formatting"
167
- },
168
- ...formattingActions.map(({ id }) => ({
169
- source: formattingGroupAction.id,
170
- target: id
171
- }))
172
- ]
173
- };
93
+ var Cursor = class _Cursor {
94
+ static {
95
+ this.converter = singleValueFacet(defaultCursorConverter);
96
+ }
97
+ static {
98
+ this.getCursorFromRange = (state, range) => {
99
+ const cursorConverter2 = state.facet(_Cursor.converter);
100
+ const from = cursorConverter2.toCursor(range.from);
101
+ const to = cursorConverter2.toCursor(range.to, -1);
102
+ return [
103
+ from,
104
+ to
105
+ ].join(":");
106
+ };
107
+ }
108
+ static {
109
+ this.getRangeFromCursor = (state, cursor) => {
110
+ const cursorConverter2 = state.facet(_Cursor.converter);
111
+ const parts = cursor.split(":");
112
+ const from = cursorConverter2.fromCursor(parts[0]);
113
+ const to = cursorConverter2.fromCursor(parts[1]);
114
+ return from !== void 0 && to !== void 0 ? {
115
+ from,
116
+ to
117
+ } : void 0;
118
+ };
119
+ }
174
120
  };
175
121
 
176
- // packages/ui/react-ui-editor/src/components/EditorToolbar/headings.ts
177
- var createHeadingGroupAction = (value) => createEditorActionGroup("heading", {
178
- variant: "dropdownMenu",
179
- applyActive: true,
180
- selectCardinality: "single",
181
- value
182
- }, "ph--text-h--regular");
183
- var createHeadingActions = (value) => Object.entries({
184
- "0": "ph--paragraph--regular",
185
- "1": "ph--text-h-one--regular",
186
- "2": "ph--text-h-two--regular",
187
- "3": "ph--text-h-three--regular",
188
- "4": "ph--text-h-four--regular",
189
- "5": "ph--text-h-five--regular",
190
- "6": "ph--text-h-six--regular"
191
- }).map(([levelStr, icon]) => {
192
- const level = parseInt(levelStr);
193
- return createEditorAction({
194
- type: "heading",
195
- data: level,
196
- checked: value === levelStr
197
- }, icon, [
198
- "heading level label",
199
- {
200
- count: level,
201
- ns: translationKey
122
+ // packages/ui/react-ui-editor/src/util/debug.ts
123
+ import { log } from "@dxos/log";
124
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util/debug.ts";
125
+ var wrapWithCatch = (fn) => {
126
+ return (...args) => {
127
+ try {
128
+ return fn(...args);
129
+ } catch (err) {
130
+ log.catch(err, void 0, {
131
+ F: __dxlog_file,
132
+ L: 15,
133
+ S: void 0,
134
+ C: (f, a) => f(...a)
135
+ });
202
136
  }
203
- ], `heading--${levelStr}`);
204
- });
205
- var computeHeadingValue = (state) => {
206
- const blockType = state ? state.blockType : "paragraph";
207
- const header = blockType && /heading(\d)/.exec(blockType);
208
- return header ? header[1] : blockType === "paragraph" || !blockType ? "0" : "";
209
- };
210
- var createHeadings = (state) => {
211
- const headingValue = computeHeadingValue(state);
212
- const headingGroupAction = createHeadingGroupAction(headingValue);
213
- const headingActions = createHeadingActions(headingValue);
214
- return {
215
- nodes: [
216
- headingGroupAction,
217
- ...headingActions
218
- ],
219
- edges: [
220
- {
221
- source: "root",
222
- target: "heading"
223
- },
224
- ...headingActions.map(({ id }) => ({
225
- source: headingGroupAction.id,
226
- target: id
227
- }))
228
- ]
229
137
  };
230
138
  };
231
-
232
- // packages/ui/react-ui-editor/src/components/EditorToolbar/lists.ts
233
- var listStyles = {
234
- bullet: "ph--list-bullets--regular",
235
- ordered: "ph--list-numbers--regular",
236
- task: "ph--list-checks--regular"
139
+ var callbackWrapper = (fn) => (...args) => {
140
+ try {
141
+ return fn(...args);
142
+ } catch (err) {
143
+ log.catch(err, void 0, {
144
+ F: __dxlog_file,
145
+ L: 29,
146
+ S: void 0,
147
+ C: (f, a) => f(...a)
148
+ });
149
+ }
237
150
  };
238
- var createListGroupAction = (value) => createEditorActionGroup("list", {
239
- variant: "toggleGroup",
240
- selectCardinality: "single",
241
- value
242
- });
243
- var createListActions = (value) => Object.entries(listStyles).map(([listStyle, icon]) => createEditorAction({
244
- type: `list-${listStyle}`,
245
- checked: value === listStyle
246
- }, icon));
247
- var createLists = (state) => {
248
- const value = state.listStyle ?? "";
249
- const listGroupAction = createListGroupAction(value);
250
- const listActionsMap = createListActions(value);
251
- return {
252
- nodes: [
253
- listGroupAction,
254
- ...listActionsMap
255
- ],
256
- edges: [
257
- {
258
- source: "root",
259
- target: "list"
260
- },
261
- ...listActionsMap.map(({ id }) => ({
262
- source: listGroupAction.id,
263
- target: id
264
- }))
265
- ]
266
- };
151
+ var debugDispatcher = (trs, view) => {
152
+ logChanges(trs);
153
+ view.update(trs);
267
154
  };
268
-
269
- // packages/ui/react-ui-editor/src/components/EditorToolbar/view-mode.ts
270
- var createViewModeGroupAction = (value) => createEditorActionGroup("viewMode", {
271
- variant: "dropdownMenu",
272
- applyActive: true,
273
- selectCardinality: "single",
274
- value
275
- }, "ph--eye--regular");
276
- var createViewModeActions = (value) => Object.entries({
277
- preview: "ph--eye--regular",
278
- source: "ph--pencil-simple--regular",
279
- readonly: "ph--pencil-slash--regular"
280
- }).map(([viewMode, icon]) => {
281
- return createEditorAction({
282
- type: "view-mode",
283
- data: viewMode,
284
- checked: viewMode === value
285
- }, icon, [
286
- `${viewMode} mode label`,
287
- {
288
- ns: translationKey
289
- }
290
- ], `view-mode--${viewMode}`);
291
- });
292
- var createViewMode = (state) => {
293
- const value = state.viewMode ?? "source";
294
- const viewModeGroupAction = createViewModeGroupAction(value);
295
- const viewModeActions = createViewModeActions(value);
296
- return {
297
- nodes: [
298
- viewModeGroupAction,
299
- ...viewModeActions
300
- ],
301
- edges: [
302
- {
303
- source: "root",
304
- target: "viewMode"
305
- },
306
- ...viewModeActions.map(({ id }) => ({
307
- source: viewModeGroupAction.id,
308
- target: id
309
- }))
310
- ]
311
- };
312
- };
313
-
314
- // packages/ui/react-ui-editor/src/defaults.ts
315
- import { EditorView } from "@codemirror/view";
316
- import { mx as mx2 } from "@dxos/react-ui-theme";
317
-
318
- // packages/ui/react-ui-editor/src/styles/markdown.ts
319
- import { mx } from "@dxos/react-ui-theme";
320
- var headings = {
321
- 1: "text-4xl",
322
- 2: "text-3xl",
323
- 3: "text-2xl",
324
- 4: "text-xl",
325
- 5: "text-lg",
326
- 6: ""
327
- };
328
- var theme = {
329
- code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
330
- codeMark: "font-mono text-primary-500",
331
- mark: "opacity-50",
332
- heading: (level) => {
333
- return mx(headings[level], "dark:text-primary-400");
334
- }
335
- };
336
-
337
- // packages/ui/react-ui-editor/src/styles/tokens.ts
338
- import get from "lodash.get";
339
- import { tokens } from "@dxos/react-ui-theme";
340
- var getToken = (path, defaultValue) => {
341
- const value = get(tokens, path, defaultValue);
342
- return value?.toString() ?? "";
343
- };
344
- var fontBody = getToken("fontFamily.body");
345
- var fontMono = getToken("fontFamily.mono");
346
-
347
- // packages/ui/react-ui-editor/src/styles/theme.ts
348
- var defaultTheme = {
349
- "&": {},
350
- "&.cm-focused": {
351
- outline: "none"
352
- },
353
- /**
354
- * Scroller
355
- */
356
- ".cm-scroller": {
357
- overflowY: "auto"
358
- },
359
- /**
360
- * Content
361
- * NOTE: Apply margins to content so that scrollbar is at the edge of the container.
362
- */
363
- ".cm-content": {
364
- padding: "unset",
365
- fontFamily: fontBody,
366
- // NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
367
- fontSize: "16px",
368
- lineHeight: 1.5,
369
- color: "unset"
370
- },
371
- /**
372
- * Gutters
373
- * NOTE: Gutters should have the same top margin as the content.
374
- */
375
- ".cm-gutters": {
376
- borderRight: "none",
377
- background: "transparent"
378
- },
379
- ".cm-gutter": {},
380
- ".cm-gutter.cm-lineNumbers": {
381
- paddingRight: "4px",
382
- borderRight: "1px solid var(--dx-separator)"
383
- },
384
- ".cm-gutter.cm-lineNumbers .cm-gutterElement": {
385
- minWidth: "40px",
386
- alignContent: "center"
387
- },
388
- /**
389
- * Height is set to match the corresponding line.
390
- */
391
- ".cm-gutterElement": {
392
- alignItems: "center",
393
- fontSize: "12px"
394
- },
395
- /**
396
- * Line.
397
- */
398
- ".cm-line": {
399
- paddingInline: 0
400
- },
401
- ".cm-activeLine": {
402
- background: "var(--dx-cmActiveLine)"
403
- },
404
- /**
405
- * Cursor (layer).
406
- */
407
- ".cm-cursor, .cm-dropCursor": {
408
- borderLeft: "2px solid var(--dx-cmCursor)"
409
- },
410
- ".cm-placeholder": {
411
- color: "var(--dx-subdued)"
412
- },
413
- /**
414
- * Selection (layer).
415
- */
416
- ".cm-selectionBackground": {
417
- background: "var(--dx-cmSelection)"
418
- },
419
- /**
420
- * Search.
421
- * NOTE: Matches comment.
422
- */
423
- ".cm-searchMatch": {
424
- margin: "0 -3px",
425
- padding: "3px",
426
- borderRadius: "3px",
427
- background: "var(--dx-cmHighlightSurface)",
428
- color: "var(--dx-cmHighlight)"
429
- },
430
- ".cm-searchMatch-selected": {
431
- textDecoration: "underline"
432
- },
433
- /**
434
- * Link.
435
- */
436
- ".cm-link": {
437
- textDecorationLine: "underline",
438
- textDecorationThickness: "1px",
439
- textDecorationColor: "var(--dx-separator)",
440
- textUnderlineOffset: "2px",
441
- borderRadius: ".125rem"
442
- },
443
- ".cm-link > span": {
444
- color: "var(--dx-accentText)"
445
- },
446
- /**
447
- * Tooltip.
448
- */
449
- ".cm-tooltip": {
450
- background: "var(--dx-baseSurface)"
451
- },
452
- ".cm-tooltip-below": {},
453
- /**
454
- * Autocomplete.
455
- * https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
456
- */
457
- ".cm-tooltip.cm-tooltip-autocomplete": {
458
- marginTop: "4px",
459
- marginLeft: "-3px"
460
- },
461
- ".cm-tooltip.cm-tooltip-autocomplete > ul": {
462
- maxHeight: "20em"
463
- },
464
- ".cm-tooltip.cm-tooltip-autocomplete > ul > li": {},
465
- ".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {},
466
- ".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
467
- paddingLeft: "4px !important",
468
- borderBottom: "none !important",
469
- color: "var(--dx-accentText)"
470
- },
471
- ".cm-tooltip.cm-completionInfo": {
472
- width: "360px !important",
473
- margin: "-10px 1px 0 1px",
474
- padding: "8px !important",
475
- borderColor: "var(--dx-separator)"
476
- },
477
- ".cm-completionIcon": {
478
- display: "none"
479
- },
480
- ".cm-completionLabel": {
481
- fontFamily: fontBody
482
- },
483
- ".cm-completionMatchedText": {
484
- textDecoration: "none !important",
485
- opacity: 0.5
486
- },
487
- /**
488
- * Panels
489
- * https://github.com/codemirror/search/blob/main/src/search.ts#L745
490
- *
491
- * Find/replace panel.
492
- * <div class="cm-announced">...</div>
493
- * <div class="cm-scroller">...</div>
494
- * <div class="cm-panels cm-panels-bottom">
495
- * <div class="cm-search cm-panel">
496
- * <input class="cm-textfield" />
497
- * <button class="cm-button">...</button>
498
- * <label><input type="checkbox" />...</label>
499
- * </div>
500
- * </div
501
- */
502
- // TODO(burdon): Implement custom panel (with icon buttons).
503
- ".cm-panels": {},
504
- ".cm-panel": {
505
- fontFamily: fontBody,
506
- backgroundColor: "var(--surface-bg)"
507
- },
508
- ".cm-panel input, .cm-panel button, .cm-panel label": {
509
- color: "var(--dx-subdued)",
510
- fontFamily: fontBody,
511
- fontSize: "14px",
512
- all: "unset",
513
- margin: "3px !important",
514
- padding: "2px 6px !important",
515
- outline: "1px solid transparent"
516
- },
517
- ".cm-panel input, .cm-panel button": {
518
- backgroundColor: "var(--dx-input)"
519
- },
520
- ".cm-panel input:focus, .cm-panel button:focus": {
521
- outline: "1px solid var(--dx-accentFocusIndicator)"
522
- },
523
- ".cm-panel label": {
524
- display: "inline-flex",
525
- alignItems: "center",
526
- cursor: "pointer"
527
- },
528
- ".cm-panel input.cm-textfield": {},
529
- ".cm-panel input[type=checkbox]": {
530
- width: "8px",
531
- height: "8px",
532
- marginRight: "6px !important",
533
- padding: "2px !important",
534
- color: "var(--dx-accentFocusIndicator)"
535
- },
536
- ".cm-panel button": {
537
- "&:hover": {
538
- backgroundColor: "var(--dx-accentSurfaceHover) !important"
539
- },
540
- "&:active": {
541
- backgroundColor: "var(--dx-accentSurfaceHover)"
542
- }
543
- },
544
- ".cm-panel.cm-search": {
545
- padding: "4px",
546
- borderTop: "1px solid var(--dx-separator)"
547
- }
548
- };
549
-
550
- // packages/ui/react-ui-editor/src/defaults.ts
551
- var margin = "!mt-[1rem]";
552
- var editorWidth = "!mli-auto is-full max-is-[min(50rem,100%-4rem)]";
553
- var editorContent = mx2(margin, editorWidth);
554
- var editorFullWidth = mx2(margin);
555
- var editorGutter = EditorView.theme({
556
- // Match margin from content.
557
- // Gutter = 2rem + 1rem margin.
558
- ".cm-gutters": {
559
- marginTop: "1rem",
560
- paddingRight: "1rem"
561
- }
562
- });
563
- var editorMonospace = EditorView.theme({
564
- ".cm-content": {
565
- fontFamily: fontMono
566
- }
567
- });
568
- var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
569
- var stackItemContentEditorClassNames = (role) => mx2("attention-surface dx-focus-ring-inset data-[toolbar=disabled]:pbs-2", role === "section" ? "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-bs-24" : "min-bs-0");
570
- var stackItemContentToolbarClassNames = (role) => mx2("attention-surface is-full border-be !border-separator relative z-[1]", role === "section" && "sticky block-start-0 -mbe-px min-is-0");
571
-
572
- // packages/ui/react-ui-editor/src/components/EditorToolbar/EditorToolbar.tsx
573
- var createToolbar = ({ state, customActions, ...features }) => {
574
- const nodes = [];
575
- const edges = [];
576
- if (features.headings ?? true) {
577
- const headings2 = createHeadings(state);
578
- nodes.push(...headings2.nodes);
579
- edges.push(...headings2.edges);
580
- }
581
- if (features.formatting ?? true) {
582
- const formatting = createFormatting(state);
583
- nodes.push(...formatting.nodes);
584
- edges.push(...formatting.edges);
585
- }
586
- if (features.lists ?? true) {
587
- const lists = createLists(state);
588
- nodes.push(...lists.nodes);
589
- edges.push(...lists.edges);
590
- }
591
- if (features.blocks ?? true) {
592
- const blocks = createBlocks(state);
593
- nodes.push(...blocks.nodes);
594
- edges.push(...blocks.edges);
595
- }
596
- if (customActions) {
597
- const custom = customActions();
598
- nodes.push(...custom.nodes);
599
- edges.push(...custom.edges);
600
- }
601
- const editorToolbarGap = createGapSeparator();
602
- nodes.push(...editorToolbarGap.nodes);
603
- edges.push(...editorToolbarGap.edges);
604
- if (features.comment ?? true) {
605
- const comment = createComment(state);
606
- nodes.push(...comment.nodes);
607
- edges.push(...comment.edges);
608
- }
609
- if (features.search ?? true) {
610
- nodes.push(editorToolbarSearch);
611
- edges.push({
612
- source: "root",
613
- target: editorToolbarSearch.id
614
- });
615
- }
616
- if (features.viewMode ?? true) {
617
- const viewMode = createViewMode(state);
618
- nodes.push(...viewMode.nodes);
619
- edges.push(...viewMode.edges);
620
- }
621
- return {
622
- nodes,
623
- edges
624
- };
625
- };
626
- var useEditorToolbarActionGraph = ({ onAction, ...props }) => {
627
- const menuCreator = useCallback(() => createToolbar(props), [
628
- props
629
- ]);
630
- const { resolveGroupItems } = useMenuActions(menuCreator);
631
- return {
632
- resolveGroupItems,
633
- onAction
634
- };
635
- };
636
- var EditorToolbar = ({ classNames, attendableId, role, ...props }) => {
637
- const menuProps = useEditorToolbarActionGraph(props);
638
- return /* @__PURE__ */ React.createElement("div", {
639
- role: "none",
640
- className: stackItemContentToolbarClassNames(role)
641
- }, /* @__PURE__ */ React.createElement(ElevationProvider, {
642
- elevation: role === "section" ? "positioned" : "base"
643
- }, /* @__PURE__ */ React.createElement(MenuProvider, {
644
- ...menuProps,
645
- attendableId
646
- }, /* @__PURE__ */ React.createElement(ToolbarMenu, {
647
- classNames: [
648
- textBlockWidth,
649
- "!bg-transparent",
650
- classNames
651
- ]
652
- }))));
653
- };
654
-
655
- // packages/ui/react-ui-editor/src/extensions/annotations.ts
656
- import { StateField } from "@codemirror/state";
657
- import { Decoration, EditorView as EditorView2 } from "@codemirror/view";
658
- import { isNotFalsy } from "@dxos/util";
659
-
660
- // packages/ui/react-ui-editor/src/util/facet.ts
661
- import { Facet } from "@codemirror/state";
662
- var singleValueFacet = (defaultValue) => Facet.define({
663
- // Called immediately.
664
- combine: (providers) => {
665
- return providers[0] ?? defaultValue;
666
- }
667
- });
668
-
669
- // packages/ui/react-ui-editor/src/util/cursor.ts
670
- var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
671
- var defaultCursorConverter = {
672
- toCursor: (position) => position.toString(),
673
- fromCursor: (cursor) => parseInt(cursor)
674
- };
675
- var Cursor = class _Cursor {
676
- static {
677
- this.converter = singleValueFacet(defaultCursorConverter);
678
- }
679
- static {
680
- this.getCursorFromRange = (state, range) => {
681
- const cursorConverter2 = state.facet(_Cursor.converter);
682
- const from = cursorConverter2.toCursor(range.from);
683
- const to = cursorConverter2.toCursor(range.to, -1);
684
- return [
685
- from,
686
- to
687
- ].join(":");
688
- };
689
- }
690
- static {
691
- this.getRangeFromCursor = (state, cursor) => {
692
- const cursorConverter2 = state.facet(_Cursor.converter);
693
- const parts = cursor.split(":");
694
- const from = cursorConverter2.fromCursor(parts[0]);
695
- const to = cursorConverter2.fromCursor(parts[1]);
696
- return from !== void 0 && to !== void 0 ? {
697
- from,
698
- to
699
- } : void 0;
700
- };
701
- }
702
- };
703
-
704
- // packages/ui/react-ui-editor/src/util/debug.ts
705
- import { log } from "@dxos/log";
706
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util/debug.ts";
707
- var wrapWithCatch = (fn) => {
708
- return (...args) => {
709
- try {
710
- return fn(...args);
711
- } catch (err) {
712
- log.catch(err, void 0, {
713
- F: __dxlog_file,
714
- L: 15,
715
- S: void 0,
716
- C: (f, a) => f(...a)
717
- });
718
- }
719
- };
720
- };
721
- var callbackWrapper = (fn) => (...args) => {
722
- try {
723
- return fn(...args);
724
- } catch (err) {
725
- log.catch(err, void 0, {
726
- F: __dxlog_file,
727
- L: 29,
728
- S: void 0,
729
- C: (f, a) => f(...a)
730
- });
731
- }
732
- };
733
- var debugDispatcher = (trs, view) => {
734
- logChanges(trs);
735
- view.update(trs);
736
- };
737
- var logChanges = (trs) => {
738
- const changes = trs.flatMap((tr) => {
739
- if (tr.changes.empty) {
740
- return void 0;
155
+ var logChanges = (trs) => {
156
+ const changes = trs.flatMap((tr) => {
157
+ if (tr.changes.empty) {
158
+ return void 0;
741
159
  }
742
160
  const changes2 = [];
743
161
  tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => changes2.push(JSON.stringify({
@@ -789,7 +207,7 @@ var clientRectsFor = (dom) => {
789
207
  };
790
208
 
791
209
  // packages/ui/react-ui-editor/src/util/react.tsx
792
- import React2 from "react";
210
+ import React from "react";
793
211
  import { createRoot } from "react-dom/client";
794
212
  import { ThemeProvider, Tooltip } from "@dxos/react-ui";
795
213
  import { defaultTx } from "@dxos/react-ui-theme";
@@ -806,15 +224,15 @@ var createElement = (tag, options, children) => {
806
224
  return el;
807
225
  };
808
226
  var renderRoot = (root, node) => {
809
- createRoot(root).render(/* @__PURE__ */ React2.createElement(ThemeProvider, {
227
+ createRoot(root).render(/* @__PURE__ */ React.createElement(ThemeProvider, {
810
228
  tx: defaultTx
811
229
  }, node));
812
230
  return root;
813
231
  };
814
232
  var createRenderer = (Component) => (el, props) => {
815
- renderRoot(el, /* @__PURE__ */ React2.createElement(ThemeProvider, {
233
+ renderRoot(el, /* @__PURE__ */ React.createElement(ThemeProvider, {
816
234
  tx: defaultTx
817
- }, /* @__PURE__ */ React2.createElement(Tooltip.Provider, null, /* @__PURE__ */ React2.createElement(Component, props))));
235
+ }, /* @__PURE__ */ React.createElement(Tooltip.Provider, null, /* @__PURE__ */ React.createElement(Component, props))));
818
236
  };
819
237
 
820
238
  // packages/ui/react-ui-editor/src/extensions/annotations.ts
@@ -854,7 +272,7 @@ var annotations = (options = {}) => {
854
272
  });
855
273
  return [
856
274
  annotationsState,
857
- EditorView2.decorations.compute([
275
+ EditorView.decorations.compute([
858
276
  annotationsState
859
277
  ], (state) => {
860
278
  const annotations2 = state.field(annotationsState);
@@ -867,7 +285,7 @@ var annotations = (options = {}) => {
867
285
  styles
868
286
  ];
869
287
  };
870
- var styles = EditorView2.theme({
288
+ var styles = EditorView.theme({
871
289
  ".cm-annotation": {
872
290
  textDecoration: "underline",
873
291
  textDecorationStyle: "wavy",
@@ -916,7 +334,7 @@ var autocomplete = ({ debug, activateOnTyping, override, onSearch } = {}) => {
916
334
 
917
335
  // packages/ui/react-ui-editor/src/extensions/automerge/automerge.ts
918
336
  import { StateField as StateField2 } from "@codemirror/state";
919
- import { EditorView as EditorView3, ViewPlugin } from "@codemirror/view";
337
+ import { EditorView as EditorView2, ViewPlugin } from "@codemirror/view";
920
338
  import { next as A3 } from "@dxos/automerge/automerge";
921
339
 
922
340
  // packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts
@@ -1200,7 +618,7 @@ var automerge = (accessor) => {
1200
618
  }
1201
619
  }),
1202
620
  // Reconcile local updates.
1203
- EditorView3.updateListener.of(({ view, changes }) => {
621
+ EditorView2.updateListener.of(({ view, changes }) => {
1204
622
  if (!changes.empty) {
1205
623
  syncer.reconcile(view, true);
1206
624
  }
@@ -1210,7 +628,7 @@ var automerge = (accessor) => {
1210
628
 
1211
629
  // packages/ui/react-ui-editor/src/extensions/awareness/awareness.ts
1212
630
  import { Annotation as Annotation2, RangeSet } from "@codemirror/state";
1213
- import { Decoration as Decoration2, EditorView as EditorView4, ViewPlugin as ViewPlugin2, WidgetType } from "@codemirror/view";
631
+ import { Decoration as Decoration2, EditorView as EditorView3, ViewPlugin as ViewPlugin2, WidgetType } from "@codemirror/view";
1214
632
  import { Event } from "@dxos/async";
1215
633
  import { Context } from "@dxos/context";
1216
634
  var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/awareness/awareness.ts";
@@ -1384,7 +802,7 @@ var RemoteCaretWidget = class extends WidgetType {
1384
802
  return true;
1385
803
  }
1386
804
  };
1387
- var styles2 = EditorView4.theme({
805
+ var styles2 = EditorView3.theme({
1388
806
  ".cm-collab-selection": {},
1389
807
  ".cm-collab-selectionLine": {
1390
808
  padding: 0,
@@ -1550,7 +968,7 @@ var SpaceAwarenessProvider = class {
1550
968
  };
1551
969
 
1552
970
  // packages/ui/react-ui-editor/src/extensions/blast.ts
1553
- import { EditorView as EditorView5, keymap as keymap2 } from "@codemirror/view";
971
+ import { EditorView as EditorView4, keymap as keymap2 } from "@codemirror/view";
1554
972
  import defaultsDeep from "lodash.defaultsdeep";
1555
973
  import { invariant as invariant2 } from "@dxos/invariant";
1556
974
  var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/blast.ts";
@@ -1598,7 +1016,7 @@ var blast = (options = defaultOptions) => {
1598
1016
  };
1599
1017
  return [
1600
1018
  // Cursor moved.
1601
- EditorView5.updateListener.of((update2) => {
1019
+ EditorView4.updateListener.of((update2) => {
1602
1020
  if (blaster?.node !== update2.view.scrollDOM) {
1603
1021
  if (blaster) {
1604
1022
  blaster.destroy();
@@ -1972,11 +1390,11 @@ var commandKeyBindings = [
1972
1390
  ];
1973
1391
 
1974
1392
  // packages/ui/react-ui-editor/src/extensions/command/command.ts
1975
- import { EditorView as EditorView7, keymap as keymap3 } from "@codemirror/view";
1393
+ import { EditorView as EditorView6, keymap as keymap3 } from "@codemirror/view";
1976
1394
 
1977
1395
  // packages/ui/react-ui-editor/src/extensions/command/hint.ts
1978
1396
  import { RangeSetBuilder } from "@codemirror/state";
1979
- import { Decoration as Decoration3, EditorView as EditorView6, ViewPlugin as ViewPlugin3, WidgetType as WidgetType2 } from "@codemirror/view";
1397
+ import { Decoration as Decoration3, EditorView as EditorView5, ViewPlugin as ViewPlugin3, WidgetType as WidgetType2 } from "@codemirror/view";
1980
1398
  var hintViewPlugin = ({ onHint }) => ViewPlugin3.fromClass(class {
1981
1399
  constructor() {
1982
1400
  this.deco = Decoration3.none;
@@ -2000,7 +1418,7 @@ var hintViewPlugin = ({ onHint }) => ViewPlugin3.fromClass(class {
2000
1418
  }
2001
1419
  }, {
2002
1420
  provide: (plugin) => [
2003
- EditorView6.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration3.none)
1421
+ EditorView5.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration3.none)
2004
1422
  ]
2005
1423
  });
2006
1424
  var CommandHint = class extends WidgetType2 {
@@ -2119,10 +1537,10 @@ var command = (options = {}) => {
2119
1537
  options.onHint ? hintViewPlugin({
2120
1538
  onHint: options.onHint
2121
1539
  }) : [],
2122
- EditorView7.focusChangeEffect.of((_, focusing) => {
1540
+ EditorView6.focusChangeEffect.of((_, focusing) => {
2123
1541
  return focusing ? closeEffect.of(null) : null;
2124
1542
  }),
2125
- EditorView7.theme({
1543
+ EditorView6.theme({
2126
1544
  ".cm-tooltip": {
2127
1545
  background: "transparent"
2128
1546
  }
@@ -2133,7 +1551,7 @@ var command = (options = {}) => {
2133
1551
  // packages/ui/react-ui-editor/src/extensions/comments.ts
2134
1552
  import { invertedEffects } from "@codemirror/commands";
2135
1553
  import { StateEffect as StateEffect3, StateField as StateField4 } from "@codemirror/state";
2136
- import { hoverTooltip, keymap as keymap5, Decoration as Decoration4, EditorView as EditorView9, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
1554
+ import { hoverTooltip, keymap as keymap5, Decoration as Decoration4, EditorView as EditorView8, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
2137
1555
  import sortBy from "lodash.sortby";
2138
1556
  import { useEffect, useMemo as useMemo2 } from "react";
2139
1557
  import { debounce as debounce2 } from "@dxos/async";
@@ -2142,7 +1560,7 @@ import { isNonNullable } from "@dxos/util";
2142
1560
 
2143
1561
  // packages/ui/react-ui-editor/src/extensions/selection.ts
2144
1562
  import { Transaction } from "@codemirror/state";
2145
- import { EditorView as EditorView8, keymap as keymap4 } from "@codemirror/view";
1563
+ import { EditorView as EditorView7, keymap as keymap4 } from "@codemirror/view";
2146
1564
  import { debounce } from "@dxos/async";
2147
1565
  import { invariant as invariant3 } from "@dxos/invariant";
2148
1566
  import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
@@ -2153,7 +1571,7 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
2153
1571
  return {
2154
1572
  selection,
2155
1573
  scrollIntoView: !scrollTo,
2156
- effects: scrollTo ? EditorView8.scrollIntoView(scrollTo, {
1574
+ effects: scrollTo ? EditorView7.scrollIntoView(scrollTo, {
2157
1575
  yMargin: 96
2158
1576
  }) : void 0,
2159
1577
  annotations: Transaction.userEvent.of(stateRestoreAnnotation)
@@ -2195,7 +1613,7 @@ var selectionState = ({ getState, setState } = {}) => {
2195
1613
  // setStateDebounced(id, {});
2196
1614
  // },
2197
1615
  // }),
2198
- EditorView8.updateListener.of(({ view, transactions }) => {
1616
+ EditorView7.updateListener.of(({ view, transactions }) => {
2199
1617
  const id = view.state.facet(documentId);
2200
1618
  if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
2201
1619
  return;
@@ -2276,7 +1694,7 @@ var commentsState = StateField4.define({
2276
1694
  return value;
2277
1695
  }
2278
1696
  });
2279
- var styles3 = EditorView9.theme({
1697
+ var styles3 = EditorView8.theme({
2280
1698
  ".cm-comment, .cm-comment-current": {
2281
1699
  margin: "0 -3px",
2282
1700
  padding: "3px",
@@ -2296,7 +1714,7 @@ var createCommentMark = (id, isCurrent) => Decoration4.mark({
2296
1714
  "data-comment-id": id
2297
1715
  }
2298
1716
  });
2299
- var commentsDecorations = EditorView9.decorations.compute([
1717
+ var commentsDecorations = EditorView8.decorations.compute([
2300
1718
  commentsState
2301
1719
  ], (state) => {
2302
1720
  const { selection: { current }, comments: comments2 } = state.field(commentsState);
@@ -2319,7 +1737,7 @@ var commentsDecorations = EditorView9.decorations.compute([
2319
1737
  return Decoration4.set(decorations);
2320
1738
  });
2321
1739
  var commentClickedEffect = StateEffect3.define();
2322
- var handleCommentClick = EditorView9.domEventHandlers({
1740
+ var handleCommentClick = EditorView8.domEventHandlers({
2323
1741
  click: (event, view) => {
2324
1742
  let target = event.target;
2325
1743
  const editorRoot = view.dom;
@@ -2358,7 +1776,7 @@ var trackPastedComments = (onUpdate) => {
2358
1776
  }
2359
1777
  };
2360
1778
  return [
2361
- EditorView9.domEventHandlers({
1779
+ EditorView8.domEventHandlers({
2362
1780
  cut: handleTrack,
2363
1781
  copy: handleTrack
2364
1782
  }),
@@ -2380,7 +1798,7 @@ var trackPastedComments = (onUpdate) => {
2380
1798
  return effects;
2381
1799
  }),
2382
1800
  // Handle paste or the undo of comment deletion.
2383
- EditorView9.updateListener.of((update2) => {
1801
+ EditorView8.updateListener.of((update2) => {
2384
1802
  const restore = [];
2385
1803
  for (let i = 0; i < update2.transactions.length; i++) {
2386
1804
  const tr = update2.transactions[i];
@@ -2439,7 +1857,7 @@ var mapTrackedComment = (comment, changes) => ({
2439
1857
  var restoreCommentEffect = StateEffect3.define({
2440
1858
  map: mapTrackedComment
2441
1859
  });
2442
- var createComment2 = (view) => {
1860
+ var createComment = (view) => {
2443
1861
  const options = view.state.facet(optionsFacet);
2444
1862
  const { from, to } = view.state.selection.main;
2445
1863
  if (from === to) {
@@ -2484,7 +1902,7 @@ var comments = (options = {}) => {
2484
1902
  options.onCreate && keymap5.of([
2485
1903
  {
2486
1904
  key: shortcut,
2487
- run: callbackWrapper(createComment2)
1905
+ run: callbackWrapper(createComment)
2488
1906
  }
2489
1907
  ]),
2490
1908
  //
@@ -2522,7 +1940,7 @@ var comments = (options = {}) => {
2522
1940
  //
2523
1941
  // Track deleted ranges and update ranges for decorations.
2524
1942
  //
2525
- EditorView9.updateListener.of(({ view, state, changes }) => {
1943
+ EditorView8.updateListener.of(({ view, state, changes }) => {
2526
1944
  let mod = false;
2527
1945
  const { comments: comments2, ...value } = state.field(commentsState);
2528
1946
  changes.iterChanges((from, to, from2, to2) => {
@@ -2554,7 +1972,7 @@ var comments = (options = {}) => {
2554
1972
  //
2555
1973
  // Track selection/proximity.
2556
1974
  //
2557
- EditorView9.updateListener.of(({ view, state }) => {
1975
+ EditorView8.updateListener.of(({ view, state }) => {
2558
1976
  let min = Infinity;
2559
1977
  const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
2560
1978
  const { head } = state.selection.main;
@@ -2608,7 +2026,7 @@ var scrollThreadIntoView = (view, id, center = true) => {
2608
2026
  anchor: range.from
2609
2027
  } : void 0,
2610
2028
  effects: [
2611
- needsScroll ? EditorView9.scrollIntoView(range.from, center ? {
2029
+ needsScroll ? EditorView8.scrollIntoView(range.from, center ? {
2612
2030
  y: "center"
2613
2031
  } : void 0) : [],
2614
2032
  needsSelectionUpdate ? setSelection.of({
@@ -2660,7 +2078,7 @@ var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin5.from
2660
2078
  }
2661
2079
  });
2662
2080
  var useCommentState = (state) => {
2663
- return useMemo2(() => EditorView9.updateListener.of((update2) => {
2081
+ return useMemo2(() => EditorView8.updateListener.of((update2) => {
2664
2082
  if (update2.docChanged || update2.selectionSet) {
2665
2083
  state.comment = selectionOverlapsComment(update2.state);
2666
2084
  state.selection = hasActiveSelection(update2.state);
@@ -2684,7 +2102,7 @@ var useComments = (view, id, comments2) => {
2684
2102
  });
2685
2103
  };
2686
2104
  var useCommentClickListener = (onCommentClick) => {
2687
- return useMemo2(() => EditorView9.updateListener.of((update2) => {
2105
+ return useMemo2(() => EditorView8.updateListener.of((update2) => {
2688
2106
  update2.transactions.forEach((transaction) => {
2689
2107
  transaction.effects.forEach((effect) => {
2690
2108
  if (effect.is(commentClickedEffect)) {
@@ -2711,8 +2129,8 @@ var debugNodeLogger = (log8 = console.log) => {
2711
2129
  };
2712
2130
 
2713
2131
  // packages/ui/react-ui-editor/src/extensions/dnd.ts
2714
- import { dropCursor, EditorView as EditorView10 } from "@codemirror/view";
2715
- var styles4 = EditorView10.theme({
2132
+ import { dropCursor, EditorView as EditorView9 } from "@codemirror/view";
2133
+ var styles4 = EditorView9.theme({
2716
2134
  ".cm-dropCursor": {
2717
2135
  borderLeft: "2px solid var(--dx-accentText)",
2718
2136
  color: "var(--dx-accentText)",
@@ -2726,7 +2144,7 @@ var dropFile = (options = {}) => {
2726
2144
  return [
2727
2145
  styles4,
2728
2146
  dropCursor(),
2729
- EditorView10.domEventHandlers({
2147
+ EditorView9.domEventHandlers({
2730
2148
  drop: (event, view) => {
2731
2149
  event.preventDefault();
2732
2150
  const files = event.dataTransfer?.files;
@@ -2753,7 +2171,7 @@ import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@cod
2753
2171
  import { searchKeymap } from "@codemirror/search";
2754
2172
  import { EditorState } from "@codemirror/state";
2755
2173
  import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
2756
- import { EditorView as EditorView12, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap6, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
2174
+ import { EditorView as EditorView11, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap6, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
2757
2175
  import defaultsDeep2 from "lodash.defaultsdeep";
2758
2176
  import merge from "lodash.merge";
2759
2177
  import { generateName } from "@dxos/display-name";
@@ -2762,7 +2180,7 @@ import { hexToHue, isNotFalsy as isNotFalsy3 } from "@dxos/util";
2762
2180
 
2763
2181
  // packages/ui/react-ui-editor/src/extensions/focus.ts
2764
2182
  import { StateEffect as StateEffect4, StateField as StateField6 } from "@codemirror/state";
2765
- import { EditorView as EditorView11 } from "@codemirror/view";
2183
+ import { EditorView as EditorView10 } from "@codemirror/view";
2766
2184
  var focusEffect = StateEffect4.define();
2767
2185
  var focusField = StateField6.define({
2768
2186
  create: () => false,
@@ -2777,7 +2195,7 @@ var focusField = StateField6.define({
2777
2195
  });
2778
2196
  var focus = [
2779
2197
  focusField,
2780
- EditorView11.domEventHandlers({
2198
+ EditorView10.domEventHandlers({
2781
2199
  focus: (event, view) => {
2782
2200
  setTimeout(() => view.dispatch({
2783
2201
  effects: focusEffect.of(true)
@@ -2791,6 +2209,238 @@ var focus = [
2791
2209
  })
2792
2210
  ];
2793
2211
 
2212
+ // packages/ui/react-ui-editor/src/styles/markdown.ts
2213
+ import { mx } from "@dxos/react-ui-theme";
2214
+ var headings = {
2215
+ 1: "text-4xl",
2216
+ 2: "text-3xl",
2217
+ 3: "text-2xl",
2218
+ 4: "text-xl",
2219
+ 5: "text-lg",
2220
+ 6: ""
2221
+ };
2222
+ var theme = {
2223
+ code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
2224
+ codeMark: "font-mono text-primary-500",
2225
+ mark: "opacity-50",
2226
+ heading: (level) => {
2227
+ return mx(headings[level], "dark:text-primary-400");
2228
+ }
2229
+ };
2230
+
2231
+ // packages/ui/react-ui-editor/src/styles/tokens.ts
2232
+ import get from "lodash.get";
2233
+ import { tokens } from "@dxos/react-ui-theme";
2234
+ var getToken = (path, defaultValue) => {
2235
+ const value = get(tokens, path, defaultValue);
2236
+ return value?.toString() ?? "";
2237
+ };
2238
+ var fontBody = getToken("fontFamily.body");
2239
+ var fontMono = getToken("fontFamily.mono");
2240
+
2241
+ // packages/ui/react-ui-editor/src/styles/theme.ts
2242
+ var defaultTheme = {
2243
+ "&": {},
2244
+ "&.cm-focused": {
2245
+ outline: "none"
2246
+ },
2247
+ /**
2248
+ * Scroller
2249
+ */
2250
+ ".cm-scroller": {
2251
+ overflowY: "auto"
2252
+ },
2253
+ /**
2254
+ * Content
2255
+ * NOTE: Apply margins to content so that scrollbar is at the edge of the container.
2256
+ */
2257
+ ".cm-content": {
2258
+ padding: "unset",
2259
+ fontFamily: fontBody,
2260
+ // NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
2261
+ fontSize: "16px",
2262
+ lineHeight: 1.5,
2263
+ color: "unset"
2264
+ },
2265
+ /**
2266
+ * Gutters
2267
+ * NOTE: Gutters should have the same top margin as the content.
2268
+ */
2269
+ ".cm-gutters": {
2270
+ borderRight: "none",
2271
+ background: "transparent"
2272
+ },
2273
+ ".cm-gutter": {},
2274
+ ".cm-gutter.cm-lineNumbers": {
2275
+ paddingRight: "4px",
2276
+ borderRight: "1px solid var(--dx-separator)"
2277
+ },
2278
+ ".cm-gutter.cm-lineNumbers .cm-gutterElement": {
2279
+ minWidth: "40px",
2280
+ alignContent: "center"
2281
+ },
2282
+ /**
2283
+ * Height is set to match the corresponding line.
2284
+ */
2285
+ ".cm-gutterElement": {
2286
+ alignItems: "center",
2287
+ fontSize: "12px"
2288
+ },
2289
+ /**
2290
+ * Line.
2291
+ */
2292
+ ".cm-line": {
2293
+ paddingInline: 0
2294
+ },
2295
+ ".cm-activeLine": {
2296
+ background: "var(--dx-cmActiveLine)"
2297
+ },
2298
+ /**
2299
+ * Cursor (layer).
2300
+ */
2301
+ ".cm-cursor, .cm-dropCursor": {
2302
+ borderLeft: "2px solid var(--dx-cmCursor)"
2303
+ },
2304
+ ".cm-placeholder": {
2305
+ color: "var(--dx-subdued)"
2306
+ },
2307
+ /**
2308
+ * Selection (layer).
2309
+ */
2310
+ ".cm-selectionBackground": {
2311
+ background: "var(--dx-cmSelection)"
2312
+ },
2313
+ /**
2314
+ * Search.
2315
+ * NOTE: Matches comment.
2316
+ */
2317
+ ".cm-searchMatch": {
2318
+ margin: "0 -3px",
2319
+ padding: "3px",
2320
+ borderRadius: "3px",
2321
+ background: "var(--dx-cmHighlightSurface)",
2322
+ color: "var(--dx-cmHighlight)"
2323
+ },
2324
+ ".cm-searchMatch-selected": {
2325
+ textDecoration: "underline"
2326
+ },
2327
+ /**
2328
+ * Link.
2329
+ */
2330
+ ".cm-link": {
2331
+ textDecorationLine: "underline",
2332
+ textDecorationThickness: "1px",
2333
+ textDecorationColor: "var(--dx-separator)",
2334
+ textUnderlineOffset: "2px",
2335
+ borderRadius: ".125rem"
2336
+ },
2337
+ ".cm-link > span": {
2338
+ color: "var(--dx-accentText)"
2339
+ },
2340
+ /**
2341
+ * Tooltip.
2342
+ */
2343
+ ".cm-tooltip": {
2344
+ background: "var(--dx-baseSurface)"
2345
+ },
2346
+ ".cm-tooltip-below": {},
2347
+ /**
2348
+ * Autocomplete.
2349
+ * https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
2350
+ */
2351
+ ".cm-tooltip.cm-tooltip-autocomplete": {
2352
+ marginTop: "4px",
2353
+ marginLeft: "-3px"
2354
+ },
2355
+ ".cm-tooltip.cm-tooltip-autocomplete > ul": {
2356
+ maxHeight: "20em"
2357
+ },
2358
+ ".cm-tooltip.cm-tooltip-autocomplete > ul > li": {},
2359
+ ".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {},
2360
+ ".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
2361
+ paddingLeft: "4px !important",
2362
+ borderBottom: "none !important",
2363
+ color: "var(--dx-accentText)"
2364
+ },
2365
+ ".cm-tooltip.cm-completionInfo": {
2366
+ width: "360px !important",
2367
+ margin: "-10px 1px 0 1px",
2368
+ padding: "8px !important",
2369
+ borderColor: "var(--dx-separator)"
2370
+ },
2371
+ ".cm-completionIcon": {
2372
+ display: "none"
2373
+ },
2374
+ ".cm-completionLabel": {
2375
+ fontFamily: fontBody
2376
+ },
2377
+ ".cm-completionMatchedText": {
2378
+ textDecoration: "none !important",
2379
+ opacity: 0.5
2380
+ },
2381
+ /**
2382
+ * Panels
2383
+ * https://github.com/codemirror/search/blob/main/src/search.ts#L745
2384
+ *
2385
+ * Find/replace panel.
2386
+ * <div class="cm-announced">...</div>
2387
+ * <div class="cm-scroller">...</div>
2388
+ * <div class="cm-panels cm-panels-bottom">
2389
+ * <div class="cm-search cm-panel">
2390
+ * <input class="cm-textfield" />
2391
+ * <button class="cm-button">...</button>
2392
+ * <label><input type="checkbox" />...</label>
2393
+ * </div>
2394
+ * </div
2395
+ */
2396
+ // TODO(burdon): Implement custom panel (with icon buttons).
2397
+ ".cm-panels": {},
2398
+ ".cm-panel": {
2399
+ fontFamily: fontBody,
2400
+ backgroundColor: "var(--surface-bg)"
2401
+ },
2402
+ ".cm-panel input, .cm-panel button, .cm-panel label": {
2403
+ color: "var(--dx-subdued)",
2404
+ fontFamily: fontBody,
2405
+ fontSize: "14px",
2406
+ all: "unset",
2407
+ margin: "3px !important",
2408
+ padding: "2px 6px !important",
2409
+ outline: "1px solid transparent"
2410
+ },
2411
+ ".cm-panel input, .cm-panel button": {
2412
+ backgroundColor: "var(--dx-input)"
2413
+ },
2414
+ ".cm-panel input:focus, .cm-panel button:focus": {
2415
+ outline: "1px solid var(--dx-accentFocusIndicator)"
2416
+ },
2417
+ ".cm-panel label": {
2418
+ display: "inline-flex",
2419
+ alignItems: "center",
2420
+ cursor: "pointer"
2421
+ },
2422
+ ".cm-panel input.cm-textfield": {},
2423
+ ".cm-panel input[type=checkbox]": {
2424
+ width: "8px",
2425
+ height: "8px",
2426
+ marginRight: "6px !important",
2427
+ padding: "2px !important",
2428
+ color: "var(--dx-accentFocusIndicator)"
2429
+ },
2430
+ ".cm-panel button": {
2431
+ "&:hover": {
2432
+ backgroundColor: "var(--dx-accentSurfaceHover) !important"
2433
+ },
2434
+ "&:active": {
2435
+ backgroundColor: "var(--dx-accentSurfaceHover)"
2436
+ }
2437
+ },
2438
+ ".cm-panel.cm-search": {
2439
+ padding: "4px",
2440
+ borderTop: "1px solid var(--dx-separator)"
2441
+ }
2442
+ };
2443
+
2794
2444
  // packages/ui/react-ui-editor/src/extensions/factories.ts
2795
2445
  var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/factories.ts";
2796
2446
  var preventNewline = EditorState.transactionFilter.of((tr) => tr.newDoc.lines > 1 ? [] : tr);
@@ -2815,7 +2465,7 @@ var createBasicExtensions = (_props) => {
2815
2465
  const props = defaultsDeep2({}, _props, defaultBasicOptions);
2816
2466
  return [
2817
2467
  // NOTE: Doesn't catch errors in keymap functions.
2818
- EditorView12.exceptionSink.of((err) => {
2468
+ EditorView11.exceptionSink.of((err) => {
2819
2469
  log5.catch(err, void 0, {
2820
2470
  F: __dxlog_file8,
2821
2471
  L: 96,
@@ -2830,12 +2480,12 @@ var createBasicExtensions = (_props) => {
2830
2480
  props.drawSelection && drawSelection({
2831
2481
  cursorBlinkRate: 1200
2832
2482
  }),
2833
- props.editable !== void 0 && EditorView12.editable.of(props.editable),
2483
+ props.editable !== void 0 && EditorView11.editable.of(props.editable),
2834
2484
  props.focus && focus,
2835
2485
  props.highlightActiveLine && highlightActiveLine(),
2836
2486
  props.history && history(),
2837
2487
  props.lineNumbers && lineNumbers(),
2838
- props.lineWrapping && EditorView12.lineWrapping,
2488
+ props.lineWrapping && EditorView11.lineWrapping,
2839
2489
  props.placeholder && placeholder(props.placeholder),
2840
2490
  props.readOnly !== void 0 && EditorState.readOnly.of(props.readOnly),
2841
2491
  props.scrollPastEnd && scrollPastEnd(),
@@ -2872,14 +2522,14 @@ var defaultThemeSlots = {
2872
2522
  var createThemeExtensions = ({ themeMode, styles: styles5, syntaxHighlighting: _syntaxHighlighting, slots: _slots } = {}) => {
2873
2523
  const slots = defaultsDeep2({}, _slots, defaultThemeSlots);
2874
2524
  return [
2875
- EditorView12.darkTheme.of(themeMode === "dark"),
2876
- EditorView12.baseTheme(styles5 ? merge({}, defaultTheme, styles5) : defaultTheme),
2525
+ EditorView11.darkTheme.of(themeMode === "dark"),
2526
+ EditorView11.baseTheme(styles5 ? merge({}, defaultTheme, styles5) : defaultTheme),
2877
2527
  // https://github.com/codemirror/theme-one-dark
2878
2528
  _syntaxHighlighting && (themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)),
2879
- slots.editor?.className && EditorView12.editorAttributes.of({
2529
+ slots.editor?.className && EditorView11.editorAttributes.of({
2880
2530
  class: slots.editor.className
2881
2531
  }),
2882
- slots.content?.className && EditorView12.contentAttributes.of({
2532
+ slots.content?.className && EditorView11.contentAttributes.of({
2883
2533
  class: slots.content.className
2884
2534
  })
2885
2535
  ].filter(isNotFalsy3);
@@ -2908,8 +2558,8 @@ var createDataExtensions = ({ id, text, space, identity }) => {
2908
2558
 
2909
2559
  // packages/ui/react-ui-editor/src/extensions/folding.tsx
2910
2560
  import { codeFolding, foldGutter } from "@codemirror/language";
2911
- import { EditorView as EditorView13 } from "@codemirror/view";
2912
- import React3 from "react";
2561
+ import { EditorView as EditorView12 } from "@codemirror/view";
2562
+ import React2 from "react";
2913
2563
  import { Icon } from "@dxos/react-ui";
2914
2564
  var folding = (_props = {}) => [
2915
2565
  codeFolding({
@@ -2922,7 +2572,7 @@ var folding = (_props = {}) => [
2922
2572
  const el = createElement("div", {
2923
2573
  className: "flex h-full items-center"
2924
2574
  });
2925
- return renderRoot(el, /* @__PURE__ */ React3.createElement(Icon, {
2575
+ return renderRoot(el, /* @__PURE__ */ React2.createElement(Icon, {
2926
2576
  icon: "ph--caret-right--bold",
2927
2577
  size: 3,
2928
2578
  classNames: [
@@ -2932,7 +2582,7 @@ var folding = (_props = {}) => [
2932
2582
  }));
2933
2583
  }
2934
2584
  }),
2935
- EditorView13.theme({
2585
+ EditorView12.theme({
2936
2586
  ".cm-foldGutter": {
2937
2587
  opacity: 0.3,
2938
2588
  transition: "opacity 0.3s",
@@ -2945,14 +2595,14 @@ var folding = (_props = {}) => [
2945
2595
  ];
2946
2596
 
2947
2597
  // packages/ui/react-ui-editor/src/extensions/listener.ts
2948
- import { EditorView as EditorView14 } from "@codemirror/view";
2598
+ import { EditorView as EditorView13 } from "@codemirror/view";
2949
2599
  var listener = ({ onFocus, onChange }) => {
2950
2600
  const extensions = [];
2951
- onFocus && extensions.push(EditorView14.focusChangeEffect.of((_, focusing) => {
2601
+ onFocus && extensions.push(EditorView13.focusChangeEffect.of((_, focusing) => {
2952
2602
  onFocus(focusing);
2953
2603
  return null;
2954
2604
  }));
2955
- onChange && extensions.push(EditorView14.updateListener.of((update2) => {
2605
+ onChange && extensions.push(EditorView13.updateListener.of((update2) => {
2956
2606
  onChange(update2.state.doc.toString(), update2.state.facet(documentId));
2957
2607
  }));
2958
2608
  return extensions;
@@ -2962,7 +2612,7 @@ var listener = ({ onFocus, onChange }) => {
2962
2612
  import { snippet } from "@codemirror/autocomplete";
2963
2613
  import { syntaxTree as syntaxTree2 } from "@codemirror/language";
2964
2614
  import { EditorSelection } from "@codemirror/state";
2965
- import { EditorView as EditorView15, keymap as keymap7 } from "@codemirror/view";
2615
+ import { EditorView as EditorView14, keymap as keymap7 } from "@codemirror/view";
2966
2616
  import { useMemo as useMemo3 } from "react";
2967
2617
  var formattingEquals = (a, b) => a.blockType === b.blockType && a.strong === b.strong && a.emphasis === b.emphasis && a.strikethrough === b.strikethrough && a.code === b.code && a.link === b.link && a.listStyle === b.listStyle && a.blockQuote === b.blockQuote;
2968
2618
  var Inline;
@@ -4051,7 +3701,7 @@ var getFormatting = (state) => {
4051
3701
  };
4052
3702
  };
4053
3703
  var useFormattingState = (state) => {
4054
- return useMemo3(() => EditorView15.updateListener.of((update2) => {
3704
+ return useMemo3(() => EditorView14.updateListener.of((update2) => {
4055
3705
  if (update2.docChanged || update2.selectionSet) {
4056
3706
  Object.entries(getFormatting(update2.state)).forEach(([key, active]) => {
4057
3707
  state[key] = active;
@@ -4099,7 +3749,7 @@ var processEditorPayload = (view, { type, data }) => {
4099
3749
  })(view);
4100
3750
  break;
4101
3751
  case "comment":
4102
- createComment2(view);
3752
+ createComment(view);
4103
3753
  break;
4104
3754
  }
4105
3755
  requestAnimationFrame(() => {
@@ -4363,9 +4013,9 @@ var convertTreeToJson = (state) => {
4363
4013
  // packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
4364
4014
  import { syntaxTree as syntaxTree7 } from "@codemirror/language";
4365
4015
  import { RangeSetBuilder as RangeSetBuilder3, StateEffect as StateEffect5 } from "@codemirror/state";
4366
- import { EditorView as EditorView19, Decoration as Decoration7, WidgetType as WidgetType5, ViewPlugin as ViewPlugin7 } from "@codemirror/view";
4016
+ import { EditorView as EditorView18, Decoration as Decoration7, WidgetType as WidgetType5, ViewPlugin as ViewPlugin7 } from "@codemirror/view";
4367
4017
  import { invariant as invariant4 } from "@dxos/invariant";
4368
- import { mx as mx3 } from "@dxos/react-ui-theme";
4018
+ import { mx as mx2 } from "@dxos/react-ui-theme";
4369
4019
 
4370
4020
  // packages/ui/react-ui-editor/src/extensions/markdown/changes.ts
4371
4021
  import { syntaxTree as syntaxTree4 } from "@codemirror/language";
@@ -4514,7 +4164,7 @@ var getValidUrl = (str) => {
4514
4164
  // packages/ui/react-ui-editor/src/extensions/markdown/image.ts
4515
4165
  import { syntaxTree as syntaxTree5 } from "@codemirror/language";
4516
4166
  import { StateField as StateField8 } from "@codemirror/state";
4517
- import { Decoration as Decoration5, EditorView as EditorView16, WidgetType as WidgetType3 } from "@codemirror/view";
4167
+ import { Decoration as Decoration5, EditorView as EditorView15, WidgetType as WidgetType3 } from "@codemirror/view";
4518
4168
  var image = (_options = {}) => {
4519
4169
  return [
4520
4170
  StateField8.define({
@@ -4542,7 +4192,7 @@ var image = (_options = {}) => {
4542
4192
  add: buildDecorations(from, to, tr.state)
4543
4193
  });
4544
4194
  },
4545
- provide: (field) => EditorView16.decorations.from(field)
4195
+ provide: (field) => EditorView15.decorations.from(field)
4546
4196
  })
4547
4197
  ];
4548
4198
  };
@@ -4602,10 +4252,10 @@ var ImageWidget = class extends WidgetType3 {
4602
4252
  };
4603
4253
 
4604
4254
  // packages/ui/react-ui-editor/src/extensions/markdown/styles.ts
4605
- import { EditorView as EditorView17 } from "@codemirror/view";
4255
+ import { EditorView as EditorView16 } from "@codemirror/view";
4606
4256
  var bulletListIndentationWidth = 24;
4607
4257
  var orderedListIndentationWidth = 36;
4608
- var formattingStyles = EditorView17.theme({
4258
+ var formattingStyles = EditorView16.theme({
4609
4259
  /**
4610
4260
  * Horizontal rule.
4611
4261
  */
@@ -4726,12 +4376,12 @@ var formattingStyles = EditorView17.theme({
4726
4376
  // packages/ui/react-ui-editor/src/extensions/markdown/table.ts
4727
4377
  import { syntaxTree as syntaxTree6 } from "@codemirror/language";
4728
4378
  import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField9 } from "@codemirror/state";
4729
- import { Decoration as Decoration6, EditorView as EditorView18, WidgetType as WidgetType4 } from "@codemirror/view";
4379
+ import { Decoration as Decoration6, EditorView as EditorView17, WidgetType as WidgetType4 } from "@codemirror/view";
4730
4380
  var table = (options = {}) => {
4731
4381
  return StateField9.define({
4732
4382
  create: (state) => update(state, options),
4733
4383
  update: (_, tr) => update(tr.state, options),
4734
- provide: (field) => EditorView18.decorations.from(field)
4384
+ provide: (field) => EditorView17.decorations.from(field)
4735
4385
  });
4736
4386
  };
4737
4387
  var update = (state, _options) => {
@@ -4917,16 +4567,16 @@ var TextWidget = class extends WidgetType5 {
4917
4567
  };
4918
4568
  var hide = Decoration7.replace({});
4919
4569
  var blockQuote = Decoration7.line({
4920
- class: mx3("cm-blockquote")
4570
+ class: mx2("cm-blockquote")
4921
4571
  });
4922
4572
  var fencedCodeLine = Decoration7.line({
4923
- class: mx3("cm-code cm-codeblock-line")
4573
+ class: mx2("cm-code cm-codeblock-line")
4924
4574
  });
4925
4575
  var fencedCodeLineFirst = Decoration7.line({
4926
- class: mx3("cm-code cm-codeblock-line", "cm-codeblock-first")
4576
+ class: mx2("cm-code cm-codeblock-line", "cm-codeblock-first")
4927
4577
  });
4928
4578
  var fencedCodeLineLast = Decoration7.line({
4929
- class: mx3("cm-code cm-codeblock-line", "cm-codeblock-last")
4579
+ class: mx2("cm-code cm-codeblock-line", "cm-codeblock-last")
4930
4580
  });
4931
4581
  var commentBlockLine = fencedCodeLine;
4932
4582
  var commentBlockLineFirst = fencedCodeLineFirst;
@@ -5224,419 +4874,838 @@ var buildDecorations2 = (view, options, focus2) => {
5224
4874
  leave: wrapWithCatch(leaveNode)
5225
4875
  });
5226
4876
  }
5227
- } else {
5228
- tree.iterate({
5229
- enter: wrapWithCatch(enterNode),
5230
- leave: wrapWithCatch(leaveNode)
5231
- });
4877
+ } else {
4878
+ tree.iterate({
4879
+ enter: wrapWithCatch(enterNode),
4880
+ leave: wrapWithCatch(leaveNode)
4881
+ });
4882
+ }
4883
+ return {
4884
+ deco: deco.finish(),
4885
+ atomicDeco: atomicDeco.finish()
4886
+ };
4887
+ };
4888
+ var forceUpdate = StateEffect5.define();
4889
+ var decorateMarkdown = (options = {}) => {
4890
+ return [
4891
+ ViewPlugin7.fromClass(class {
4892
+ constructor(view) {
4893
+ ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(view, options, view.hasFocus));
4894
+ }
4895
+ update(update2) {
4896
+ if (update2.docChanged || update2.viewportChanged || update2.focusChanged || update2.transactions.some((tr) => tr.effects.some((effect) => effect.is(forceUpdate))) || update2.selectionSet && !options.selectionChangeDelay) {
4897
+ ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(update2.view, options, update2.view.hasFocus));
4898
+ this.clearUpdate();
4899
+ } else if (update2.selectionSet) {
4900
+ this.scheduleUpdate(update2.view);
4901
+ }
4902
+ }
4903
+ // Defer update in case moving through the document.
4904
+ scheduleUpdate(view) {
4905
+ this.clearUpdate();
4906
+ this.pendingUpdate = setTimeout(() => {
4907
+ view.dispatch({
4908
+ effects: forceUpdate.of(null)
4909
+ });
4910
+ }, options.selectionChangeDelay);
4911
+ }
4912
+ clearUpdate() {
4913
+ if (this.pendingUpdate) {
4914
+ clearTimeout(this.pendingUpdate);
4915
+ this.pendingUpdate = void 0;
4916
+ }
4917
+ }
4918
+ destroy() {
4919
+ this.clearUpdate();
4920
+ }
4921
+ }, {
4922
+ provide: (plugin) => [
4923
+ EditorView18.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
4924
+ EditorView18.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
4925
+ EditorView18.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration7.none)
4926
+ ]
4927
+ }),
4928
+ image(),
4929
+ table(),
4930
+ adjustChanges(),
4931
+ formattingStyles
4932
+ ];
4933
+ };
4934
+
4935
+ // packages/ui/react-ui-editor/src/extensions/markdown/link.ts
4936
+ import { syntaxTree as syntaxTree8 } from "@codemirror/language";
4937
+ import { hoverTooltip as hoverTooltip2 } from "@codemirror/view";
4938
+ import { tooltipContent } from "@dxos/react-ui-theme";
4939
+ var linkTooltip = (renderTooltip) => {
4940
+ return hoverTooltip2((view, pos, side) => {
4941
+ const syntax = syntaxTree8(view.state).resolveInner(pos, side);
4942
+ let link = null;
4943
+ for (let i = 0, node = syntax; !link && node && i < 5; node = node.parent, i++) {
4944
+ link = node.name === "Link" ? node : null;
4945
+ }
4946
+ const url = link && link.getChild("URL");
4947
+ if (!url || !link) {
4948
+ return null;
4949
+ }
4950
+ const urlText = view.state.sliceDoc(url.from, url.to);
4951
+ return {
4952
+ pos: link.from,
4953
+ end: link.to,
4954
+ // NOTE: Forcing above causes the tooltip to flicker.
4955
+ // above: true,
4956
+ create: () => {
4957
+ const el = document.createElement("div");
4958
+ el.className = tooltipContent({});
4959
+ renderTooltip(el, {
4960
+ url: urlText
4961
+ }, view);
4962
+ return {
4963
+ dom: el,
4964
+ offset: {
4965
+ x: 0,
4966
+ y: 4
4967
+ }
4968
+ };
4969
+ }
4970
+ };
4971
+ }, {
4972
+ // NOTE: 0 = default of 300ms.
4973
+ hoverTime: 1
4974
+ });
4975
+ };
4976
+
4977
+ // packages/ui/react-ui-editor/src/extensions/mention.ts
4978
+ import { autocompletion as autocompletion2 } from "@codemirror/autocomplete";
4979
+ import { log as log6 } from "@dxos/log";
4980
+ var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/mention.ts";
4981
+ var mention = ({ debug, onSearch }) => {
4982
+ return autocompletion2({
4983
+ // TODO(burdon): Not working.
4984
+ activateOnTyping: true,
4985
+ // activateOnTypingDelay: 100,
4986
+ // selectOnOpen: true,
4987
+ closeOnBlur: !debug,
4988
+ // defaultKeymap: false,
4989
+ icons: false,
4990
+ override: [
4991
+ (context) => {
4992
+ log6.info("completion context", {
4993
+ context
4994
+ }, {
4995
+ F: __dxlog_file10,
4996
+ L: 27,
4997
+ S: void 0,
4998
+ C: (f, a) => f(...a)
4999
+ });
5000
+ const match = context.matchBefore(/@(\w+)?/);
5001
+ if (!match || match.from === match.to && !context.explicit) {
5002
+ return null;
5003
+ }
5004
+ return {
5005
+ from: match.from,
5006
+ options: onSearch(match.text.slice(1).toLowerCase()).map((value) => ({
5007
+ label: `@${value}`
5008
+ }))
5009
+ };
5010
+ }
5011
+ ]
5012
+ });
5013
+ };
5014
+
5015
+ // packages/ui/react-ui-editor/src/extensions/modes.ts
5016
+ import { keymap as keymap9 } from "@codemirror/view";
5017
+ import { vim } from "@replit/codemirror-vim";
5018
+ import { vscodeKeymap } from "@replit/codemirror-vscode-keymap";
5019
+ import { Schema } from "effect";
5020
+ var EditorViewModes = [
5021
+ "preview",
5022
+ "readonly",
5023
+ "source"
5024
+ ];
5025
+ var EditorViewMode = Schema.Union(...EditorViewModes.map((mode) => Schema.Literal(mode)));
5026
+ var EditorInputModes = [
5027
+ "default",
5028
+ "vim",
5029
+ "vscode"
5030
+ ];
5031
+ var EditorInputMode = Schema.Union(...EditorInputModes.map((mode) => Schema.Literal(mode)));
5032
+ var editorInputMode = singleValueFacet({});
5033
+ var InputModeExtensions = {
5034
+ default: [],
5035
+ vscode: [
5036
+ // https://github.com/replit/codemirror-vscode-keymap
5037
+ editorInputMode.of({
5038
+ type: "vscode"
5039
+ }),
5040
+ keymap9.of(vscodeKeymap)
5041
+ ],
5042
+ vim: [
5043
+ // https://github.com/replit/codemirror-vim
5044
+ vim(),
5045
+ editorInputMode.of({
5046
+ type: "vim",
5047
+ noTabster: true
5048
+ }),
5049
+ keymap9.of([
5050
+ {
5051
+ key: "Alt-Escape",
5052
+ run: (view) => {
5053
+ view.dom.parentElement?.focus();
5054
+ return true;
5055
+ }
5056
+ }
5057
+ ])
5058
+ ]
5059
+ };
5060
+
5061
+ // packages/ui/react-ui-editor/src/extensions/preview/preview.ts
5062
+ import "@dxos/lit-ui/dx-ref-tag.pcss";
5063
+ import { syntaxTree as syntaxTree9 } from "@codemirror/language";
5064
+ import { RangeSetBuilder as RangeSetBuilder4, StateField as StateField10 } from "@codemirror/state";
5065
+ import { Decoration as Decoration8, EditorView as EditorView19, WidgetType as WidgetType6 } from "@codemirror/view";
5066
+ var preview = (options = {}) => {
5067
+ return [
5068
+ // NOTE: Atomic block decorations must be created from a state field, now a widget, otherwise it results in the following error:
5069
+ // "Block decorations may not be specified via plugins"
5070
+ StateField10.define({
5071
+ create: (state) => buildDecorations3(state, options),
5072
+ update: (_, tr) => buildDecorations3(tr.state, options),
5073
+ provide: (field) => [
5074
+ EditorView19.decorations.from(field),
5075
+ EditorView19.atomicRanges.of((view) => view.state.field(field))
5076
+ ]
5077
+ }),
5078
+ EditorView19.theme({
5079
+ ".cm-preview-block": {
5080
+ marginLeft: "-1rem",
5081
+ marginRight: "-1rem",
5082
+ padding: "1rem",
5083
+ borderRadius: "0.5rem",
5084
+ background: "var(--dx-modalSurface)",
5085
+ border: "1px solid var(--dx-separator)"
5086
+ }
5087
+ })
5088
+ ];
5089
+ };
5090
+ var getLinkRef = (state, node) => {
5091
+ const mark = node.getChild("LinkMark");
5092
+ const label = node.getChild("LinkLabel");
5093
+ if (mark && label) {
5094
+ const ref = state.sliceDoc(label.from + 1, label.to - 1);
5095
+ return {
5096
+ suggest: ref.startsWith("?"),
5097
+ block: state.sliceDoc(mark.from, mark.from + 1) === "!",
5098
+ label: state.sliceDoc(mark.to, label.from - 1),
5099
+ ref: ref.startsWith("?") ? ref.slice(1) : ref
5100
+ };
5101
+ }
5102
+ };
5103
+ var buildDecorations3 = (state, options) => {
5104
+ const builder = new RangeSetBuilder4();
5105
+ syntaxTree9(state).iterate({
5106
+ enter: (node) => {
5107
+ switch (node.name) {
5108
+ //
5109
+ // Decoration.
5110
+ // [Label][dxn:echo:123]
5111
+ //
5112
+ case "Link": {
5113
+ const link = getLinkRef(state, node.node);
5114
+ if (link) {
5115
+ builder.add(node.from, node.to, Decoration8.replace({
5116
+ widget: new PreviewInlineWidget(options, link)
5117
+ }));
5118
+ }
5119
+ break;
5120
+ }
5121
+ //
5122
+ // Block widget.
5123
+ // ![Label][dxn:echo:123]
5124
+ //
5125
+ case "Image": {
5126
+ const link = getLinkRef(state, node.node);
5127
+ if (options.renderBlock && link) {
5128
+ builder.add(node.from, node.to, Decoration8.replace({
5129
+ block: true,
5130
+ // atomic: true,
5131
+ widget: new PreviewBlockWidget(options, link)
5132
+ }));
5133
+ }
5134
+ break;
5135
+ }
5136
+ }
5137
+ }
5138
+ });
5139
+ return builder.finish();
5140
+ };
5141
+ var PreviewInlineWidget = class extends WidgetType6 {
5142
+ constructor(_options, _link) {
5143
+ super();
5144
+ this._options = _options;
5145
+ this._link = _link;
5146
+ }
5147
+ // override ignoreEvent() {
5148
+ // return false;
5149
+ // }
5150
+ eq(other) {
5151
+ return this._link.ref === other._link.ref && this._link.label === other._link.label;
5152
+ }
5153
+ toDOM(view) {
5154
+ const root = document.createElement("dx-ref-tag");
5155
+ root.textContent = this._link.label;
5156
+ root.setAttribute("ref", this._link.ref);
5157
+ return root;
5232
5158
  }
5233
- return {
5234
- deco: deco.finish(),
5235
- atomicDeco: atomicDeco.finish()
5236
- };
5237
5159
  };
5238
- var forceUpdate = StateEffect5.define();
5239
- var decorateMarkdown = (options = {}) => {
5240
- return [
5241
- ViewPlugin7.fromClass(class {
5242
- constructor(view) {
5243
- ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(view, options, view.hasFocus));
5160
+ var PreviewBlockWidget = class extends WidgetType6 {
5161
+ constructor(_options, _link) {
5162
+ super();
5163
+ this._options = _options;
5164
+ this._link = _link;
5165
+ }
5166
+ // override ignoreEvent() {
5167
+ // return true;
5168
+ // }
5169
+ eq(other) {
5170
+ return this._link.ref === other._link.ref;
5171
+ }
5172
+ toDOM(view) {
5173
+ const root = document.createElement("div");
5174
+ root.classList.add("cm-preview-block");
5175
+ const handleAction = (action) => {
5176
+ const pos = view.posAtDOM(root);
5177
+ const node = syntaxTree9(view.state).resolve(pos + 1).node.parent;
5178
+ if (!node) {
5179
+ return;
5244
5180
  }
5245
- update(update2) {
5246
- if (update2.docChanged || update2.viewportChanged || update2.focusChanged || update2.transactions.some((tr) => tr.effects.some((effect) => effect.is(forceUpdate))) || update2.selectionSet && !options.selectionChangeDelay) {
5247
- ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(update2.view, options, update2.view.hasFocus));
5248
- this.clearUpdate();
5249
- } else if (update2.selectionSet) {
5250
- this.scheduleUpdate(update2.view);
5251
- }
5181
+ const link = getLinkRef(view.state, node);
5182
+ if (link?.ref !== action.link.ref) {
5183
+ return;
5252
5184
  }
5253
- // Defer update in case moving through the document.
5254
- scheduleUpdate(view) {
5255
- this.clearUpdate();
5256
- this.pendingUpdate = setTimeout(() => {
5185
+ switch (action.type) {
5186
+ // TODO(burdon): Should we dispatch to the view or mutate the document? (i.e., handle externally?)
5187
+ // Insert ref text.
5188
+ case "insert": {
5257
5189
  view.dispatch({
5258
- effects: forceUpdate.of(null)
5190
+ changes: {
5191
+ from: node.from,
5192
+ to: node.to,
5193
+ insert: action.target.text
5194
+ }
5259
5195
  });
5260
- }, options.selectionChangeDelay);
5261
- }
5262
- clearUpdate() {
5263
- if (this.pendingUpdate) {
5264
- clearTimeout(this.pendingUpdate);
5265
- this.pendingUpdate = void 0;
5196
+ break;
5197
+ }
5198
+ // Remove ref.
5199
+ case "delete": {
5200
+ view.dispatch({
5201
+ changes: {
5202
+ from: node.from,
5203
+ to: node.to
5204
+ }
5205
+ });
5206
+ break;
5266
5207
  }
5267
5208
  }
5268
- destroy() {
5269
- this.clearUpdate();
5209
+ };
5210
+ this._options.renderBlock(root, {
5211
+ readonly: view.state.readOnly,
5212
+ link: this._link,
5213
+ onAction: handleAction,
5214
+ onLookup: this._options.onLookup
5215
+ }, view);
5216
+ return root;
5217
+ }
5218
+ };
5219
+
5220
+ // packages/ui/react-ui-editor/src/extensions/typewriter.ts
5221
+ import { keymap as keymap10 } from "@codemirror/view";
5222
+ var defaultItems = [
5223
+ "hello world!",
5224
+ "this is a test.",
5225
+ "this is [DXOS](https://dxos.org)"
5226
+ ];
5227
+ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
5228
+ let t;
5229
+ let idx = 0;
5230
+ return [
5231
+ keymap10.of([
5232
+ {
5233
+ // Reset.
5234
+ key: "alt-meta-'",
5235
+ run: (view) => {
5236
+ clearTimeout(t);
5237
+ idx = 0;
5238
+ return true;
5239
+ }
5240
+ },
5241
+ {
5242
+ // Next prompt.
5243
+ // TODO(burdon): Press 1-9 to select prompt?
5244
+ key: "shift-meta-'",
5245
+ run: (view) => {
5246
+ clearTimeout(t);
5247
+ const text = items[idx++];
5248
+ if (idx === items?.length) {
5249
+ idx = 0;
5250
+ }
5251
+ let i = 0;
5252
+ const insert = (d = 0) => {
5253
+ t = setTimeout(() => {
5254
+ const pos = view.state.selection.main.head;
5255
+ view.dispatch({
5256
+ changes: {
5257
+ from: pos,
5258
+ insert: text[i++]
5259
+ },
5260
+ selection: {
5261
+ anchor: pos + 1
5262
+ }
5263
+ });
5264
+ if (i < text.length) {
5265
+ insert(Math.random() * delay * (text[i] === " " ? 2 : 1));
5266
+ }
5267
+ }, d);
5268
+ };
5269
+ insert();
5270
+ return true;
5271
+ }
5270
5272
  }
5271
- }, {
5272
- provide: (plugin) => [
5273
- EditorView19.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
5274
- EditorView19.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
5275
- EditorView19.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration7.none)
5276
- ]
5277
- }),
5278
- image(),
5279
- table(),
5280
- adjustChanges(),
5281
- formattingStyles
5273
+ ])
5282
5274
  ];
5283
5275
  };
5284
5276
 
5285
- // packages/ui/react-ui-editor/src/extensions/markdown/link.ts
5286
- import { syntaxTree as syntaxTree8 } from "@codemirror/language";
5287
- import { hoverTooltip as hoverTooltip2 } from "@codemirror/view";
5288
- import { tooltipContent } from "@dxos/react-ui-theme";
5289
- var linkTooltip = (renderTooltip) => {
5290
- return hoverTooltip2((view, pos, side) => {
5291
- const syntax = syntaxTree8(view.state).resolveInner(pos, side);
5292
- let link = null;
5293
- for (let i = 0, node = syntax; !link && node && i < 5; node = node.parent, i++) {
5294
- link = node.name === "Link" ? node : null;
5277
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/blocks.ts
5278
+ var createBlockGroupAction = (value) => createEditorActionGroup("block", {
5279
+ variant: "toggleGroup",
5280
+ selectCardinality: "single",
5281
+ value
5282
+ });
5283
+ var createBlockActions = (value, getView, blankLine) => Object.entries({
5284
+ blockquote: "ph--quotes--regular",
5285
+ codeblock: "ph--code-block--regular",
5286
+ table: "ph--table--regular"
5287
+ }).map(([type, icon]) => {
5288
+ const checked = type === value;
5289
+ return createEditorAction(type, () => {
5290
+ const view = getView();
5291
+ if (!view) {
5292
+ return;
5295
5293
  }
5296
- const url = link && link.getChild("URL");
5297
- if (!url || !link) {
5298
- return null;
5294
+ switch (type) {
5295
+ case "blockquote":
5296
+ checked ? removeBlockquote(view) : addBlockquote(view);
5297
+ break;
5298
+ case "codeblock":
5299
+ checked ? removeCodeblock(view) : addCodeblock(view);
5300
+ break;
5301
+ case "table":
5302
+ insertTable(view);
5303
+ break;
5299
5304
  }
5300
- const urlText = view.state.sliceDoc(url.from, url.to);
5301
- return {
5302
- pos: link.from,
5303
- end: link.to,
5304
- // NOTE: Forcing above causes the tooltip to flicker.
5305
- // above: true,
5306
- create: () => {
5307
- const el = document.createElement("div");
5308
- el.className = tooltipContent({});
5309
- renderTooltip(el, {
5310
- url: urlText
5311
- }, view);
5312
- return {
5313
- dom: el,
5314
- offset: {
5315
- x: 0,
5316
- y: 4
5317
- }
5318
- };
5305
+ }, {
5306
+ checked,
5307
+ ...type === "table" && {
5308
+ disabled: !!blankLine
5309
+ },
5310
+ icon
5311
+ });
5312
+ });
5313
+ var createBlocks = (state, getView) => {
5314
+ const value = state?.blockQuote ? "blockquote" : state.blockType ?? "";
5315
+ const blockGroupAction = createBlockGroupAction(value);
5316
+ const blockActions = createBlockActions(value, getView, state.blankLine);
5317
+ return {
5318
+ nodes: [
5319
+ blockGroupAction,
5320
+ ...blockActions
5321
+ ],
5322
+ edges: [
5323
+ {
5324
+ source: "root",
5325
+ target: "block"
5326
+ },
5327
+ ...blockActions.map(({ id }) => ({
5328
+ source: blockGroupAction.id,
5329
+ target: id
5330
+ }))
5331
+ ]
5332
+ };
5333
+ };
5334
+
5335
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/comment.ts
5336
+ var commentLabel = (comment, selection) => comment ? "selection overlaps existing comment label" : selection === false ? "select text to comment label" : "comment label";
5337
+ var createCommentAction = (label, getView) => createEditorAction("comment", () => createComment(getView()), {
5338
+ testId: "editor.toolbar.comment",
5339
+ icon: "ph--chat-text--regular",
5340
+ label
5341
+ });
5342
+ var createComment2 = (state, getView) => ({
5343
+ nodes: [
5344
+ createCommentAction([
5345
+ commentLabel(state.comment, state.selection),
5346
+ {
5347
+ ns: translationKey
5319
5348
  }
5320
- };
5349
+ ], getView)
5350
+ ],
5351
+ edges: [
5352
+ {
5353
+ source: "root",
5354
+ target: "comment"
5355
+ }
5356
+ ]
5357
+ });
5358
+
5359
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/formatting.ts
5360
+ var formats = {
5361
+ strong: "ph--text-b--regular",
5362
+ emphasis: "ph--text-italic--regular",
5363
+ strikethrough: "ph--text-strikethrough--regular",
5364
+ code: "ph--code--regular",
5365
+ link: "ph--link--regular"
5366
+ };
5367
+ var createFormattingGroup = (formatting) => createEditorActionGroup("formatting", {
5368
+ variant: "toggleGroup",
5369
+ selectCardinality: "multiple",
5370
+ value: Object.keys(formats).filter((key) => !!formatting[key])
5371
+ });
5372
+ var createFormattingActions = (formatting, getView) => Object.entries(formats).map(([type, icon]) => {
5373
+ const checked = !!formatting[type];
5374
+ return createEditorAction(type, () => {
5375
+ const view = getView();
5376
+ if (!view) {
5377
+ return;
5378
+ }
5379
+ if (type === "link") {
5380
+ checked ? removeLink(view) : addLink()(view);
5381
+ return;
5382
+ }
5383
+ const inlineType = type === "strong" ? Inline.Strong : type === "emphasis" ? Inline.Emphasis : type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
5384
+ setStyle(inlineType, !checked)(view);
5321
5385
  }, {
5322
- // NOTE: 0 = default of 300ms.
5323
- hoverTime: 1
5386
+ checked,
5387
+ icon
5324
5388
  });
5389
+ });
5390
+ var createFormatting = (state, getView) => {
5391
+ const formattingGroupAction = createFormattingGroup(state);
5392
+ const formattingActions = createFormattingActions(state, getView);
5393
+ return {
5394
+ nodes: [
5395
+ formattingGroupAction,
5396
+ ...formattingActions
5397
+ ],
5398
+ edges: [
5399
+ {
5400
+ source: "root",
5401
+ target: "formatting"
5402
+ },
5403
+ ...formattingActions.map(({ id }) => ({
5404
+ source: formattingGroupAction.id,
5405
+ target: id
5406
+ }))
5407
+ ]
5408
+ };
5325
5409
  };
5326
5410
 
5327
- // packages/ui/react-ui-editor/src/extensions/mention.ts
5328
- import { autocompletion as autocompletion2 } from "@codemirror/autocomplete";
5329
- import { log as log6 } from "@dxos/log";
5330
- var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/mention.ts";
5331
- var mention = ({ debug, onSearch }) => {
5332
- return autocompletion2({
5333
- // TODO(burdon): Not working.
5334
- activateOnTyping: true,
5335
- // activateOnTypingDelay: 100,
5336
- // selectOnOpen: true,
5337
- closeOnBlur: !debug,
5338
- // defaultKeymap: false,
5339
- icons: false,
5340
- override: [
5341
- (context) => {
5342
- log6.info("completion context", {
5343
- context
5344
- }, {
5345
- F: __dxlog_file10,
5346
- L: 27,
5347
- S: void 0,
5348
- C: (f, a) => f(...a)
5349
- });
5350
- const match = context.matchBefore(/@(\w+)?/);
5351
- if (!match || match.from === match.to && !context.explicit) {
5352
- return null;
5353
- }
5354
- return {
5355
- from: match.from,
5356
- options: onSearch(match.text.slice(1).toLowerCase()).map((value) => ({
5357
- label: `@${value}`
5358
- }))
5359
- };
5411
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/headings.ts
5412
+ var createHeadingGroupAction = (value) => createEditorActionGroup("heading", {
5413
+ variant: "dropdownMenu",
5414
+ applyActive: true,
5415
+ selectCardinality: "single",
5416
+ value
5417
+ }, "ph--text-h--regular");
5418
+ var createHeadingActions = (getView) => Object.entries({
5419
+ "0": "ph--paragraph--regular",
5420
+ "1": "ph--text-h-one--regular",
5421
+ "2": "ph--text-h-two--regular",
5422
+ "3": "ph--text-h-three--regular",
5423
+ "4": "ph--text-h-four--regular",
5424
+ "5": "ph--text-h-five--regular",
5425
+ "6": "ph--text-h-six--regular"
5426
+ }).map(([levelStr, icon]) => {
5427
+ const level = parseInt(levelStr);
5428
+ return createEditorAction(`heading--${levelStr}`, () => setHeading(level)(getView()), {
5429
+ label: [
5430
+ "heading level label",
5431
+ {
5432
+ count: level,
5433
+ ns: translationKey
5360
5434
  }
5361
- ]
5435
+ ],
5436
+ icon
5362
5437
  });
5438
+ });
5439
+ var computeHeadingValue = (state) => {
5440
+ const blockType = state ? state.blockType : "paragraph";
5441
+ const header = blockType && /heading(\d)/.exec(blockType);
5442
+ return header ? header[1] : blockType === "paragraph" || !blockType ? "0" : "";
5443
+ };
5444
+ var createHeadings = (state, getView) => {
5445
+ const headingValue = computeHeadingValue(state);
5446
+ const headingGroupAction = createHeadingGroupAction(headingValue);
5447
+ const headingActions = createHeadingActions(getView);
5448
+ return {
5449
+ nodes: [
5450
+ headingGroupAction,
5451
+ ...headingActions
5452
+ ],
5453
+ edges: [
5454
+ {
5455
+ source: "root",
5456
+ target: "heading"
5457
+ },
5458
+ ...headingActions.map(({ id }) => ({
5459
+ source: headingGroupAction.id,
5460
+ target: id
5461
+ }))
5462
+ ]
5463
+ };
5363
5464
  };
5364
5465
 
5365
- // packages/ui/react-ui-editor/src/extensions/modes.ts
5366
- import { keymap as keymap9 } from "@codemirror/view";
5367
- import { vim } from "@replit/codemirror-vim";
5368
- import { vscodeKeymap } from "@replit/codemirror-vscode-keymap";
5369
- import { S } from "@dxos/echo-schema";
5370
- var EditorViewModes = [
5371
- "preview",
5372
- "readonly",
5373
- "source"
5374
- ];
5375
- var EditorViewMode = S.Union(...EditorViewModes.map((mode) => S.Literal(mode)));
5376
- var EditorInputModes = [
5377
- "default",
5378
- "vim",
5379
- "vscode"
5380
- ];
5381
- var EditorInputMode = S.Union(...EditorInputModes.map((mode) => S.Literal(mode)));
5382
- var editorInputMode = singleValueFacet({});
5383
- var InputModeExtensions = {
5384
- default: [],
5385
- vscode: [
5386
- // https://github.com/replit/codemirror-vscode-keymap
5387
- editorInputMode.of({
5388
- type: "vscode"
5389
- }),
5390
- keymap9.of(vscodeKeymap)
5466
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/image.ts
5467
+ var createImageUploadAction = (onImageUpload) => createEditorAction("image", onImageUpload, {
5468
+ testId: "editor.toolbar.image",
5469
+ icon: "ph--image-square--regular"
5470
+ });
5471
+ var createImageUpload = (onImageUpload) => ({
5472
+ nodes: [
5473
+ createImageUploadAction(onImageUpload)
5391
5474
  ],
5392
- vim: [
5393
- // https://github.com/replit/codemirror-vim
5394
- vim(),
5395
- editorInputMode.of({
5396
- type: "vim",
5397
- noTabster: true
5398
- }),
5399
- keymap9.of([
5400
- {
5401
- key: "Alt-Escape",
5402
- run: (view) => {
5403
- view.dom.parentElement?.focus();
5404
- return true;
5405
- }
5406
- }
5407
- ])
5475
+ edges: [
5476
+ {
5477
+ source: "root",
5478
+ target: "image"
5479
+ }
5408
5480
  ]
5409
- };
5481
+ });
5410
5482
 
5411
- // packages/ui/react-ui-editor/src/extensions/preview/preview.ts
5412
- import "@dxos/lit-ui/dx-ref-tag.pcss";
5413
- import { syntaxTree as syntaxTree9 } from "@codemirror/language";
5414
- import { RangeSetBuilder as RangeSetBuilder4, StateField as StateField10 } from "@codemirror/state";
5415
- import { Decoration as Decoration8, EditorView as EditorView20, WidgetType as WidgetType6 } from "@codemirror/view";
5416
- var preview = (options = {}) => {
5417
- return [
5418
- // NOTE: Atomic block decorations must be created from a state field, now a widget, otherwise it results in the following error:
5419
- // "Block decorations may not be specified via plugins"
5420
- StateField10.define({
5421
- create: (state) => buildDecorations3(state, options),
5422
- update: (_, tr) => buildDecorations3(tr.state, options),
5423
- provide: (field) => [
5424
- EditorView20.decorations.from(field),
5425
- EditorView20.atomicRanges.of((view) => view.state.field(field))
5426
- ]
5427
- }),
5428
- EditorView20.theme({
5429
- ".cm-preview-block": {
5430
- marginLeft: "-1rem",
5431
- marginRight: "-1rem",
5432
- padding: "1rem",
5433
- borderRadius: "0.5rem",
5434
- background: "var(--dx-modalSurface)",
5435
- border: "1px solid var(--dx-separator)"
5436
- }
5437
- })
5438
- ];
5439
- };
5440
- var getLinkRef = (state, node) => {
5441
- const mark = node.getChild("LinkMark");
5442
- const label = node.getChild("LinkLabel");
5443
- if (mark && label) {
5444
- const ref = state.sliceDoc(label.from + 1, label.to - 1);
5445
- return {
5446
- suggest: ref.startsWith("?"),
5447
- block: state.sliceDoc(mark.from, mark.from + 1) === "!",
5448
- label: state.sliceDoc(mark.to, label.from - 1),
5449
- ref: ref.startsWith("?") ? ref.slice(1) : ref
5450
- };
5451
- }
5483
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/lists.ts
5484
+ var listStyles = {
5485
+ bullet: "ph--list-bullets--regular",
5486
+ ordered: "ph--list-numbers--regular",
5487
+ task: "ph--list-checks--regular"
5452
5488
  };
5453
- var buildDecorations3 = (state, options) => {
5454
- const builder = new RangeSetBuilder4();
5455
- syntaxTree9(state).iterate({
5456
- enter: (node) => {
5457
- switch (node.name) {
5458
- //
5459
- // Decoration.
5460
- // [Label][dxn:echo:123]
5461
- //
5462
- case "Link": {
5463
- const link = getLinkRef(state, node.node);
5464
- if (link) {
5465
- builder.add(node.from, node.to, Decoration8.replace({
5466
- widget: new PreviewInlineWidget(options, link)
5467
- }));
5468
- }
5469
- break;
5470
- }
5471
- //
5472
- // Block widget.
5473
- // ![Label][dxn:echo:123]
5474
- //
5475
- case "Image": {
5476
- const link = getLinkRef(state, node.node);
5477
- if (options.renderBlock && link) {
5478
- builder.add(node.from, node.to, Decoration8.replace({
5479
- block: true,
5480
- // atomic: true,
5481
- widget: new PreviewBlockWidget(options, link)
5482
- }));
5483
- }
5484
- break;
5485
- }
5486
- }
5489
+ var createListGroupAction = (value) => createEditorActionGroup("list", {
5490
+ variant: "toggleGroup",
5491
+ selectCardinality: "single",
5492
+ value
5493
+ });
5494
+ var createListActions = (value, getView) => Object.entries(listStyles).map(([listStyle, icon]) => {
5495
+ const checked = value === listStyle;
5496
+ return createEditorAction(`list-${listStyle}`, () => {
5497
+ const view = getView();
5498
+ if (!view) {
5499
+ return;
5500
+ }
5501
+ const listType = listStyle === "ordered" ? List.Ordered : listStyle === "bullet" ? List.Bullet : List.Task;
5502
+ if (checked) {
5503
+ removeList(listType)(view);
5504
+ } else {
5505
+ addList(listType)(view);
5506
+ }
5507
+ }, {
5508
+ checked,
5509
+ icon
5510
+ });
5511
+ });
5512
+ var createLists = (state, getView) => {
5513
+ const value = state.listStyle ?? "";
5514
+ const listGroupAction = createListGroupAction(value);
5515
+ const listActionsMap = createListActions(value, getView);
5516
+ return {
5517
+ nodes: [
5518
+ listGroupAction,
5519
+ ...listActionsMap
5520
+ ],
5521
+ edges: [
5522
+ {
5523
+ source: "root",
5524
+ target: "list"
5525
+ },
5526
+ ...listActionsMap.map(({ id }) => ({
5527
+ source: listGroupAction.id,
5528
+ target: id
5529
+ }))
5530
+ ]
5531
+ };
5532
+ };
5533
+
5534
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/search.ts
5535
+ import { openSearchPanel } from "@codemirror/search";
5536
+ var createSearchAction = (getView) => createEditorAction("search", () => openSearchPanel(getView()), {
5537
+ testId: "editor.toolbar.search",
5538
+ icon: "ph--magnifying-glass--regular"
5539
+ });
5540
+ var createSearch = (getView) => ({
5541
+ nodes: [
5542
+ createSearchAction(getView)
5543
+ ],
5544
+ edges: [
5545
+ {
5546
+ source: "root",
5547
+ target: "search"
5487
5548
  }
5549
+ ]
5550
+ });
5551
+
5552
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/view-mode.ts
5553
+ var createViewModeGroupAction = (value) => createEditorActionGroup("viewMode", {
5554
+ variant: "dropdownMenu",
5555
+ applyActive: true,
5556
+ selectCardinality: "single",
5557
+ value
5558
+ }, "ph--eye--regular");
5559
+ var createViewModeActions = (value, onViewModeChange) => Object.entries({
5560
+ preview: "ph--eye--regular",
5561
+ source: "ph--pencil-simple--regular",
5562
+ readonly: "ph--pencil-slash--regular"
5563
+ }).map(([viewMode, icon]) => {
5564
+ const checked = viewMode === value;
5565
+ return createEditorAction(`view-mode--${viewMode}`, () => onViewModeChange(viewMode), {
5566
+ label: [
5567
+ `${viewMode} mode label`,
5568
+ {
5569
+ ns: translationKey
5570
+ }
5571
+ ],
5572
+ checked,
5573
+ icon
5488
5574
  });
5489
- return builder.finish();
5575
+ });
5576
+ var createViewMode = (state, onViewModeChange) => {
5577
+ const value = state.viewMode ?? "source";
5578
+ const viewModeGroupAction = createViewModeGroupAction(value);
5579
+ const viewModeActions = createViewModeActions(value, onViewModeChange);
5580
+ return {
5581
+ nodes: [
5582
+ viewModeGroupAction,
5583
+ ...viewModeActions
5584
+ ],
5585
+ edges: [
5586
+ {
5587
+ source: "root",
5588
+ target: "viewMode"
5589
+ },
5590
+ ...viewModeActions.map(({ id }) => ({
5591
+ source: viewModeGroupAction.id,
5592
+ target: id
5593
+ }))
5594
+ ]
5595
+ };
5490
5596
  };
5491
- var PreviewInlineWidget = class extends WidgetType6 {
5492
- constructor(_options, _link) {
5493
- super();
5494
- this._options = _options;
5495
- this._link = _link;
5597
+
5598
+ // packages/ui/react-ui-editor/src/defaults.ts
5599
+ import { EditorView as EditorView20 } from "@codemirror/view";
5600
+ import { mx as mx3 } from "@dxos/react-ui-theme";
5601
+ var margin = "!mt-[1rem]";
5602
+ var editorWidth = "!mli-auto is-full max-is-[min(50rem,100%-4rem)]";
5603
+ var editorContent = mx3(margin, editorWidth);
5604
+ var editorFullWidth = mx3(margin);
5605
+ var editorGutter = EditorView20.theme({
5606
+ // Match margin from content.
5607
+ // Gutter = 2rem + 1rem margin.
5608
+ ".cm-gutters": {
5609
+ marginTop: "1rem",
5610
+ paddingRight: "1rem"
5496
5611
  }
5497
- // override ignoreEvent() {
5498
- // return false;
5499
- // }
5500
- eq(other) {
5501
- return this._link.ref === other._link.ref && this._link.label === other._link.label;
5612
+ });
5613
+ var editorMonospace = EditorView20.theme({
5614
+ ".cm-content": {
5615
+ fontFamily: fontMono
5502
5616
  }
5503
- toDOM(view) {
5504
- const root = document.createElement("dx-ref-tag");
5505
- root.setAttribute("label", this._link.label);
5506
- root.setAttribute("ref", this._link.ref);
5507
- return root;
5617
+ });
5618
+ var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
5619
+ var stackItemContentEditorClassNames = (role) => mx3("attention-surface dx-focus-ring-inset data-[toolbar=disabled]:pbs-2", role === "section" ? "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-bs-24" : "min-bs-0");
5620
+ var stackItemContentToolbarClassNames = (role) => mx3("attention-surface is-full border-be !border-separator relative z-[1]", role === "section" && "sticky block-start-0 -mbe-px min-is-0");
5621
+
5622
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/EditorToolbar.tsx
5623
+ var createToolbar = ({ getView, state, customActions, ...features }) => {
5624
+ const nodes = [];
5625
+ const edges = [];
5626
+ if (features.headings ?? true) {
5627
+ const headings2 = createHeadings(state, getView);
5628
+ nodes.push(...headings2.nodes);
5629
+ edges.push(...headings2.edges);
5508
5630
  }
5509
- };
5510
- var PreviewBlockWidget = class extends WidgetType6 {
5511
- constructor(_options, _link) {
5512
- super();
5513
- this._options = _options;
5514
- this._link = _link;
5631
+ if (features.formatting ?? true) {
5632
+ const formatting = createFormatting(state, getView);
5633
+ nodes.push(...formatting.nodes);
5634
+ edges.push(...formatting.edges);
5515
5635
  }
5516
- // override ignoreEvent() {
5517
- // return true;
5518
- // }
5519
- eq(other) {
5520
- return this._link.ref === other._link.ref;
5636
+ if (features.lists ?? true) {
5637
+ const lists = createLists(state, getView);
5638
+ nodes.push(...lists.nodes);
5639
+ edges.push(...lists.edges);
5521
5640
  }
5522
- toDOM(view) {
5523
- const root = document.createElement("div");
5524
- root.classList.add("cm-preview-block");
5525
- const handleAction = (action) => {
5526
- const pos = view.posAtDOM(root);
5527
- const node = syntaxTree9(view.state).resolve(pos + 1).node.parent;
5528
- if (!node) {
5529
- return;
5530
- }
5531
- const link = getLinkRef(view.state, node);
5532
- if (link?.ref !== action.link.ref) {
5533
- return;
5534
- }
5535
- switch (action.type) {
5536
- // TODO(burdon): Should we dispatch to the view or mutate the document? (i.e., handle externally?)
5537
- // Insert ref text.
5538
- case "insert": {
5539
- view.dispatch({
5540
- changes: {
5541
- from: node.from,
5542
- to: node.to,
5543
- insert: action.target.text
5544
- }
5545
- });
5546
- break;
5547
- }
5548
- // Remove ref.
5549
- case "delete": {
5550
- view.dispatch({
5551
- changes: {
5552
- from: node.from,
5553
- to: node.to
5554
- }
5555
- });
5556
- break;
5557
- }
5558
- }
5559
- };
5560
- this._options.renderBlock(root, {
5561
- readonly: view.state.readOnly,
5562
- link: this._link,
5563
- onAction: handleAction,
5564
- onLookup: this._options.onLookup
5565
- }, view);
5566
- return root;
5641
+ if (features.blocks ?? true) {
5642
+ const blocks = createBlocks(state, getView);
5643
+ nodes.push(...blocks.nodes);
5644
+ edges.push(...blocks.edges);
5567
5645
  }
5646
+ if (features.image) {
5647
+ const image2 = createImageUpload(features.image);
5648
+ nodes.push(...image2.nodes);
5649
+ edges.push(...image2.edges);
5650
+ }
5651
+ if (customActions) {
5652
+ const custom = customActions();
5653
+ nodes.push(...custom.nodes);
5654
+ edges.push(...custom.edges);
5655
+ }
5656
+ const editorToolbarGap = createGapSeparator();
5657
+ nodes.push(...editorToolbarGap.nodes);
5658
+ edges.push(...editorToolbarGap.edges);
5659
+ if (features.comment) {
5660
+ const comment = createComment2(state, getView);
5661
+ nodes.push(...comment.nodes);
5662
+ edges.push(...comment.edges);
5663
+ }
5664
+ if (features.search ?? true) {
5665
+ const search = createSearch(getView);
5666
+ nodes.push(...search.nodes);
5667
+ edges.push(...search.edges);
5668
+ }
5669
+ if (features.viewMode) {
5670
+ const viewMode = createViewMode(state, features.viewMode);
5671
+ nodes.push(...viewMode.nodes);
5672
+ edges.push(...viewMode.edges);
5673
+ }
5674
+ return {
5675
+ nodes,
5676
+ edges
5677
+ };
5568
5678
  };
5569
-
5570
- // packages/ui/react-ui-editor/src/extensions/typewriter.ts
5571
- import { keymap as keymap10 } from "@codemirror/view";
5572
- var defaultItems = [
5573
- "hello world!",
5574
- "this is a test.",
5575
- "this is [DXOS](https://dxos.org)"
5576
- ];
5577
- var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
5578
- let t;
5579
- let idx = 0;
5580
- return [
5581
- keymap10.of([
5582
- {
5583
- // Reset.
5584
- key: "alt-meta-'",
5585
- run: (view) => {
5586
- clearTimeout(t);
5587
- idx = 0;
5588
- return true;
5589
- }
5590
- },
5591
- {
5592
- // Next prompt.
5593
- // TODO(burdon): Press 1-9 to select prompt?
5594
- key: "shift-meta-'",
5595
- run: (view) => {
5596
- clearTimeout(t);
5597
- const text = items[idx++];
5598
- if (idx === items?.length) {
5599
- idx = 0;
5600
- }
5601
- let i = 0;
5602
- const insert = (d = 0) => {
5603
- t = setTimeout(() => {
5604
- const pos = view.state.selection.main.head;
5605
- view.dispatch({
5606
- changes: {
5607
- from: pos,
5608
- insert: text[i++]
5609
- },
5610
- selection: {
5611
- anchor: pos + 1
5612
- }
5613
- });
5614
- if (i < text.length) {
5615
- insert(Math.random() * delay * (text[i] === " " ? 2 : 1));
5616
- }
5617
- }, d);
5618
- };
5619
- insert();
5620
- return true;
5621
- }
5622
- }
5623
- ])
5624
- ];
5625
- };
5626
-
5627
- // packages/ui/react-ui-editor/src/hooks/useActionHandler.ts
5628
- import { useCallback as useCallback2 } from "react";
5629
- var useActionHandler = (view) => {
5630
- return useCallback2((action) => view && processEditorPayload(view, action.properties), [
5631
- view
5679
+ var useEditorToolbarActionGraph = (props) => {
5680
+ const menuCreator = useCallback(() => createToolbar(props), [
5681
+ props
5632
5682
  ]);
5683
+ return useMenuActions(menuCreator);
5633
5684
  };
5685
+ var EditorToolbar = /* @__PURE__ */ memo(({ classNames, attendableId, role, ...props }) => {
5686
+ const menuProps = useEditorToolbarActionGraph(props);
5687
+ return /* @__PURE__ */ React3.createElement("div", {
5688
+ role: "none",
5689
+ className: stackItemContentToolbarClassNames(role)
5690
+ }, /* @__PURE__ */ React3.createElement(ElevationProvider, {
5691
+ elevation: role === "section" ? "positioned" : "base"
5692
+ }, /* @__PURE__ */ React3.createElement(MenuProvider, {
5693
+ ...menuProps,
5694
+ attendableId
5695
+ }, /* @__PURE__ */ React3.createElement(ToolbarMenu, {
5696
+ classNames: [
5697
+ textBlockWidth,
5698
+ "!bg-transparent",
5699
+ classNames
5700
+ ]
5701
+ }))));
5702
+ });
5634
5703
 
5635
5704
  // packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
5636
5705
  import { EditorState as EditorState2 } from "@codemirror/state";
5637
5706
  import { EditorView as EditorView21 } from "@codemirror/view";
5638
5707
  import { useFocusableGroup } from "@fluentui/react-tabster";
5639
- import { useCallback as useCallback3, useEffect as useEffect2, useMemo as useMemo4, useRef, useState } from "react";
5708
+ import { useCallback as useCallback2, useEffect as useEffect2, useMemo as useMemo4, useRef, useState } from "react";
5640
5709
  import { log as log7 } from "@dxos/log";
5641
5710
  import { getProviderValue, isNotFalsy as isNotFalsy4 } from "@dxos/util";
5642
5711
  var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
@@ -5761,7 +5830,7 @@ var useTextEditor = (props = {}, deps = []) => {
5761
5830
  Escape: view?.state.facet(editorInputMode).noTabster
5762
5831
  }
5763
5832
  });
5764
- const handleKeyUp = useCallback3((event) => {
5833
+ const handleKeyUp = useCallback2((event) => {
5765
5834
  const { key, target, currentTarget } = event;
5766
5835
  if (target === currentTarget) {
5767
5836
  switch (key) {
@@ -5820,7 +5889,7 @@ export {
5820
5889
  commentsState,
5821
5890
  convertTreeToJson,
5822
5891
  createBasicExtensions,
5823
- createComment2 as createComment,
5892
+ createComment,
5824
5893
  createDataExtensions,
5825
5894
  createEditorAction,
5826
5895
  createEditorActionGroup,
@@ -5898,7 +5967,6 @@ export {
5898
5967
  toggleStyle,
5899
5968
  translations_default as translations,
5900
5969
  typewriter,
5901
- useActionHandler,
5902
5970
  useCommentClickListener,
5903
5971
  useCommentState,
5904
5972
  useComments,